@jxsuite/studio 6.1.2 → 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 (522) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  4. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  5. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  6. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  7. package/dist/chunks/{color-area-0fj8a4ga.js → color-area-6rbra5dy.js} +2 -2
  8. package/dist/chunks/{color-field-xch8kx2g.js → color-field-gy56c94g.js} +3 -3
  9. package/dist/chunks/color-m7r1vk54.js +4 -0
  10. package/dist/chunks/{color-slider-jxd8v350.js → color-slider-sqqdyf6c.js} +2 -2
  11. package/dist/chunks/{combobox-p0efwjke.js → combobox-72h32ejk.js} +3 -3
  12. package/dist/chunks/components-r22xca09.js +4 -0
  13. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  14. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  15. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  16. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  17. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  18. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  19. package/dist/chunks/files-rcn56qvm.js +4 -0
  20. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  21. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  22. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  23. package/dist/chunks/{grid-view-d2wq9ezg.js → grid-view-qg1b5eqx.js} +25 -25
  24. package/dist/chunks/{icons-pnfz478q.js → icons-63bjtbs7.js} +2 -2
  25. package/dist/chunks/{iframe-entry-jdcktez8.js → iframe-entry-2zggzajv.js} +4 -4
  26. package/dist/chunks/{iframe-entry-zap785cw.js → iframe-entry-76j8vwwx.js} +4 -4
  27. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  28. package/dist/chunks/{iframe-entry-x0ygf2yr.js → iframe-entry-pkgmcgp0.js} +4 -4
  29. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  30. package/dist/chunks/{index-zpjmzqfk.js → index-32eqzv1k.js} +3 -3
  31. package/dist/chunks/index-f0jn7nnp.js +4 -0
  32. package/dist/chunks/{javascript-m54mnwp6.js → javascript-pjp734q4.js} +3 -3
  33. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  34. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  35. package/dist/chunks/layers-bgyr11tr.js +4 -0
  36. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  37. package/dist/chunks/{listbox-e74qjyq6.js → listbox-c421cf8c.js} +2 -2
  38. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  39. package/dist/chunks/media-library-sq468wts.js +4 -0
  40. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  41. package/dist/chunks/{menu-n6yzswmy.js → menu-bdpzbfvs.js} +2 -2
  42. package/dist/chunks/{monaco-binding-7gx83x3r.js → monaco-binding-vq1hgnn0.js} +3 -3
  43. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  44. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  45. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  46. package/dist/chunks/parse-v77xtwv7.js +4 -0
  47. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  48. package/dist/chunks/popover-b89sfej7.js +4 -0
  49. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  50. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  51. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  52. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  53. package/dist/chunks/references-9547rg5s.js +4 -0
  54. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  55. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  56. package/dist/chunks/{split-n2gfpm5m.js → split-c9zfdgxf.js} +2 -2
  57. package/dist/chunks/studio-03ct6yfv.js +9 -0
  58. package/dist/chunks/studio-07rcfje3.js +5 -0
  59. package/dist/chunks/studio-3e54qh39.js +7 -0
  60. package/dist/chunks/studio-3exxhz5g.js +5 -0
  61. package/dist/chunks/studio-3q40e3rj.js +5 -0
  62. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  63. package/dist/chunks/studio-3qqjeep5.js +6 -0
  64. package/dist/chunks/studio-43sd2mam.js +4 -0
  65. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  66. package/dist/chunks/studio-58xg6j2q.js +9 -0
  67. package/dist/chunks/studio-5g0rprdt.js +7 -0
  68. package/dist/chunks/{studio-2j1cb95x.js → studio-6m380wp7.js} +4 -4
  69. package/dist/chunks/studio-80jyh1xh.js +4 -0
  70. package/dist/chunks/studio-83mk4bgg.js +9 -0
  71. package/dist/chunks/{studio-v0jzqdjm.js → studio-881z1xrx.js} +4 -4
  72. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  73. package/dist/chunks/{studio-d81xfh1g.js → studio-8tr6cfrc.js} +4 -4
  74. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  75. package/dist/chunks/studio-9tmebf0s.js +5 -0
  76. package/dist/chunks/studio-a2bvaptz.js +5 -0
  77. package/dist/chunks/studio-b7y5mr30.js +5 -0
  78. package/dist/chunks/studio-bavb31r0.js +5 -0
  79. package/dist/chunks/{studio-dgz8d0c1.js → studio-bbe4c90a.js} +4 -4
  80. package/dist/chunks/studio-c05wdnt3.js +5 -0
  81. package/dist/chunks/studio-ccv2svc6.js +5 -0
  82. package/dist/chunks/studio-d5grtb9e.js +16 -0
  83. package/dist/chunks/studio-df0baea9.js +5 -0
  84. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  85. package/dist/chunks/studio-e1g64q43.js +5 -0
  86. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  87. package/dist/chunks/studio-ed3xx40h.js +7 -0
  88. package/dist/chunks/studio-f14e1zdj.js +5 -0
  89. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  90. package/dist/chunks/studio-fyh0jc96.js +5 -0
  91. package/dist/chunks/studio-gcxk20n7.js +5 -0
  92. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  93. package/dist/chunks/{studio-90pq9km1.js → studio-jcnsdaep.js} +4 -4
  94. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  95. package/dist/chunks/{studio-0q988f9w.js → studio-k3xxbagr.js} +3 -3
  96. package/dist/chunks/{studio-5ve6bbep.js → studio-k7evxqh4.js} +4 -4
  97. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  98. package/dist/chunks/studio-m8g16bgz.js +5 -0
  99. package/dist/chunks/studio-mn0476ag.js +5 -0
  100. package/dist/chunks/studio-mx1smyq0.js +5 -0
  101. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  102. package/dist/chunks/{studio-485046te.js → studio-nh6d342n.js} +7 -7
  103. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  104. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  105. package/dist/chunks/{studio-1fxkaaea.js → studio-pbxa5fpc.js} +4 -4
  106. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  107. package/dist/chunks/studio-ph84avkf.js +5 -0
  108. package/dist/chunks/{studio-tq0rtfwj.js → studio-q0mvbaq6.js} +4 -4
  109. package/dist/chunks/studio-q0tccd43.js +5 -0
  110. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  111. package/dist/chunks/{studio-a3g98wjr.js → studio-qgh13jtz.js} +4 -4
  112. package/dist/chunks/studio-qmn1xc24.js +5 -0
  113. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  114. package/dist/chunks/studio-r5qy30vx.js +5 -0
  115. package/dist/chunks/studio-rj9eamf8.js +5 -0
  116. package/dist/chunks/studio-rptgsk96.js +5 -0
  117. package/dist/chunks/studio-rthyg42z.js +928 -0
  118. package/dist/chunks/studio-s19tp1xr.js +5 -0
  119. package/dist/chunks/studio-s32578pn.js +5 -0
  120. package/dist/chunks/studio-svb7yyve.js +5 -0
  121. package/dist/chunks/studio-syreb644.js +5 -0
  122. package/dist/chunks/studio-tf9jryb1.js +10 -0
  123. package/dist/chunks/studio-tfkznv39.js +5 -0
  124. package/dist/chunks/studio-tft6r105.js +5 -0
  125. package/dist/chunks/studio-txf2kysx.js +5 -0
  126. package/dist/chunks/studio-v8867ddv.js +12 -0
  127. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  128. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  129. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  130. package/dist/chunks/studio-wc649wss.js +5 -0
  131. package/dist/chunks/studio-wys23mxz.js +5 -0
  132. package/dist/chunks/studio-x1x167jh.js +5 -0
  133. package/dist/chunks/studio-x9hsze61.js +5 -0
  134. package/dist/chunks/studio-y0n7yxea.js +9 -0
  135. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  136. package/dist/chunks/studio-z97c48fk.js +5 -0
  137. package/dist/chunks/studio-zat62m0c.js +5 -0
  138. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  139. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  140. package/dist/chunks/toast-1gv0h53h.js +4 -0
  141. package/dist/chunks/{toast-host-ke5z4ng7.js → toast-host-1yg5ar8d.js} +3 -3
  142. package/dist/chunks/{tooltip-5v8ngwj2.js → tooltip-yypz28gq.js} +3 -3
  143. package/dist/chunks/{tree-mdq3v5cw.js → tree-9xa4hm7n.js} +2 -2
  144. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  145. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  146. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  147. package/dist/chunks/{ws-client-nze0k6mv.js → ws-client-bv552sfx.js} +3 -3
  148. package/dist/iframe-entry.js +20 -16
  149. package/dist/manifest.json +77 -63
  150. package/dist/studio.js +103 -104
  151. package/dist/workers/ts.worker.js +3 -3
  152. package/package.json +12 -11
  153. package/src/browse/component-examples.ts +272 -0
  154. package/src/browse/library-commands.ts +64 -104
  155. package/src/browse/library-layouts.ts +263 -49
  156. package/src/browse/library-model.ts +181 -133
  157. package/src/browse/library-pane.ts +738 -446
  158. package/src/browse/library-preview.ts +149 -19
  159. package/src/browse/library-source.ts +308 -41
  160. package/src/browse/preview-root.ts +78 -0
  161. package/src/browse/preview-style.ts +155 -0
  162. package/src/canvas/asset-refs.ts +16 -1
  163. package/src/canvas/canvas-live-render.ts +222 -30
  164. package/src/canvas/canvas-origin.ts +37 -12
  165. package/src/canvas/canvas-page-context.ts +112 -0
  166. package/src/canvas/canvas-render.ts +113 -107
  167. package/src/canvas/canvas-utils.ts +57 -12
  168. package/src/canvas/iframe-drop.ts +107 -0
  169. package/src/canvas/iframe-entry.ts +24 -12
  170. package/src/canvas/iframe-host.ts +134 -62
  171. package/src/canvas/iframe-keys.ts +11 -0
  172. package/src/canvas/iframe-patch.ts +8 -7
  173. package/src/canvas/iframe-protocol.ts +24 -5
  174. package/src/canvas/iframe-render.ts +48 -1
  175. package/src/canvas/iframe-subtree.ts +5 -2
  176. package/src/canvas/npm-modules.ts +22 -0
  177. package/src/canvas/preview-navigate.ts +16 -0
  178. package/src/canvas/repeater-sources.ts +200 -0
  179. package/src/canvas/stage-scrollbar.ts +5 -1
  180. package/src/canvas/surface-registry.ts +6 -0
  181. package/src/commands/app-commands.ts +16 -6
  182. package/src/commands/budget.ts +10 -8
  183. package/src/commands/context.ts +35 -10
  184. package/src/commands/defaults.ts +69 -45
  185. package/src/commands/keymap.ts +9 -0
  186. package/src/commands/levels.ts +11 -5
  187. package/src/commands/live-context.ts +2 -0
  188. package/src/commands/registry.ts +10 -1
  189. package/src/content/collection-match.ts +6 -5
  190. package/src/content/collection-pages.ts +412 -0
  191. package/src/content/content-collections.ts +270 -0
  192. package/src/content/entry-commands.ts +51 -60
  193. package/src/content/entry-editor.ts +111 -18
  194. package/src/content/entry-fields.ts +13 -1
  195. package/src/content/entry-inspector.ts +225 -0
  196. package/src/content/entry-model.ts +17 -3
  197. package/src/content/entry-open.ts +80 -0
  198. package/src/content/entry-summaries.ts +440 -0
  199. package/src/content/file-record-ids.ts +80 -0
  200. package/src/content/file-records.ts +125 -0
  201. package/src/content/page-summaries.ts +129 -0
  202. package/src/content/record-entry.ts +201 -0
  203. package/src/content/writing-banner.ts +177 -0
  204. package/src/create/add-new-commands.ts +185 -0
  205. package/src/create/add-new-flow.ts +1116 -0
  206. package/src/create/add-new.ts +1014 -0
  207. package/src/create/element-name.ts +121 -0
  208. package/src/editor/convert-to-component.ts +67 -43
  209. package/src/editor/file-drop-action.ts +9 -1
  210. package/src/editor/inline-edit-apply.ts +44 -0
  211. package/src/editor/inline-edit.ts +10 -0
  212. package/src/editor/insert-component.ts +91 -0
  213. package/src/editor/insert-zone-action.ts +13 -4
  214. package/src/editor/shortcuts.ts +44 -22
  215. package/src/editor/slash-menu.ts +51 -8
  216. package/src/files/components.ts +74 -10
  217. package/src/files/file-ops.ts +15 -5
  218. package/src/files/files.ts +164 -150
  219. package/src/files/fs-events.ts +18 -7
  220. package/src/files/media-meta.ts +95 -1
  221. package/src/files/media-types.ts +55 -0
  222. package/src/files/media-upload.ts +209 -52
  223. package/src/files/new-file-name.ts +156 -0
  224. package/src/files/serialize-document.ts +13 -3
  225. package/src/format/format-host.ts +15 -0
  226. package/src/github/github-auth.ts +2 -2
  227. package/src/github/github-publish.ts +4 -3
  228. package/src/grid/grid-controller.ts +5 -1
  229. package/src/grid/grid-open.ts +0 -27
  230. package/src/grid/grid-panel.ts +54 -2
  231. package/src/grid/grid-reveal.ts +34 -0
  232. package/src/grid/grid-source.ts +3 -25
  233. package/src/grid/grid-view.ts +31 -6
  234. package/src/grid/sources/content-source.ts +75 -7
  235. package/src/grid/tabulator-tables.d.ts +6 -0
  236. package/src/hosting/document.ts +2 -2
  237. package/src/i18n/i18n-commands.ts +2 -1
  238. package/src/media/media-commands.ts +181 -0
  239. package/src/media/media-library-model.ts +232 -0
  240. package/src/media/media-library.ts +1283 -0
  241. package/src/media/media-pane.ts +47 -19
  242. package/src/packages/pull-package-sync.ts +1 -1
  243. package/src/panels/activity-panel.ts +21 -5
  244. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  245. package/src/panels/block-action-bar.ts +11 -11
  246. package/src/panels/canvas-dnd-bridge.ts +5 -2
  247. package/src/panels/chat-panel.ts +6 -6
  248. package/src/panels/collections-panel.ts +306 -0
  249. package/src/panels/component-preview.ts +35 -13
  250. package/src/panels/data-explorer.ts +1 -1
  251. package/src/panels/data-grid.ts +4 -0
  252. package/src/panels/dnd.ts +17 -30
  253. package/src/panels/elements-panel.ts +9 -2
  254. package/src/panels/empty-state.ts +2 -2
  255. package/src/panels/formula-workspace.ts +2 -3
  256. package/src/panels/frontmatter-fields.ts +9 -9
  257. package/src/panels/git-diff-open.ts +9 -5
  258. package/src/panels/head-panel.ts +369 -103
  259. package/src/panels/i18n-panel.ts +11 -10
  260. package/src/panels/imports-panel.ts +2 -0
  261. package/src/panels/jump-bar.ts +27 -2
  262. package/src/panels/layers-panel.ts +36 -30
  263. package/src/panels/left-panel.ts +22 -8
  264. package/src/panels/navigator-panels.ts +23 -11
  265. package/src/panels/pane-context.ts +111 -29
  266. package/src/panels/pane-grid.ts +6 -6
  267. package/src/panels/panel-registry.ts +14 -9
  268. package/src/panels/properties-panel.ts +7 -3
  269. package/src/panels/right-panel.ts +199 -43
  270. package/src/panels/seo-modal.ts +41 -108
  271. package/src/panels/settings-menu.ts +52 -50
  272. package/src/panels/settings-pane.ts +268 -162
  273. package/src/panels/signals-panel.ts +3 -4
  274. package/src/panels/site-model.ts +367 -0
  275. package/src/panels/site-panel.ts +638 -0
  276. package/src/panels/style-panel.ts +37 -3
  277. package/src/panels/stylebook-doc.ts +142 -10
  278. package/src/panels/stylebook-layers-panel.ts +39 -80
  279. package/src/panels/stylebook-panel.ts +47 -10
  280. package/src/panels/styles-panel.ts +327 -0
  281. package/src/panels/tab-strip.ts +109 -25
  282. package/src/platform.ts +1 -1
  283. package/src/platforms/cloud.ts +28 -1
  284. package/src/platforms/default-platform.ts +4 -4
  285. package/src/platforms/devserver.ts +51 -25
  286. package/src/publish/deploy-checklist.ts +12 -7
  287. package/src/publish/pages-service.ts +38 -14
  288. package/src/publish/publish-changes.ts +491 -0
  289. package/src/publish/publish-commands.ts +83 -18
  290. package/src/publish/publish-ids.ts +49 -0
  291. package/src/publish/publish-quick.ts +148 -0
  292. package/src/publish/publish-workspace.ts +926 -0
  293. package/src/publish/source-control.ts +907 -0
  294. package/src/services/automation.ts +16 -20
  295. package/src/services/cf-settings.ts +4 -4
  296. package/src/services/connection.ts +2 -2
  297. package/src/services/directory-picker.ts +2 -2
  298. package/src/services/references.ts +0 -0
  299. package/src/services/render-critic.ts +21 -2
  300. package/src/services/settings/definitions.ts +25 -14
  301. package/src/settings/contributed-section.ts +49 -10
  302. package/src/settings/css-vars-editor.ts +93 -27
  303. package/src/settings/developer-panels.ts +43 -0
  304. package/src/settings/extension-sections.ts +20 -2
  305. package/src/settings/general-settings.ts +91 -21
  306. package/src/settings/preferences-dialog.ts +8 -1
  307. package/src/settings/project-sections.ts +27 -10
  308. package/src/settings/schema-field-ui.ts +3 -1
  309. package/src/settings/section-registry.ts +116 -11
  310. package/src/settings/settings-dialog.ts +192 -0
  311. package/src/settings/settings-document.ts +182 -162
  312. package/src/shell.ts +467 -431
  313. package/src/site-context.ts +64 -10
  314. package/src/state.ts +28 -9
  315. package/src/studio.ts +194 -41
  316. package/src/style/project-styles.ts +34 -0
  317. package/src/style/stylebook-specimens.ts +89 -0
  318. package/src/style/stylebook-target.ts +26 -0
  319. package/src/style/tag-inheritance.ts +105 -0
  320. package/src/style/variables-focus.ts +61 -0
  321. package/src/style/variables-view.ts +235 -0
  322. package/src/surfaces/add-new.json +1482 -0
  323. package/src/surfaces/add-new.ts +325 -0
  324. package/src/surfaces/ai-chat.ts +2 -2
  325. package/src/surfaces/boot-failure.json +4 -3
  326. package/src/surfaces/bottom-dock.json +1 -1
  327. package/src/surfaces/canvas-stage.json +30 -19
  328. package/src/surfaces/canvas-stage.ts +5 -5
  329. package/src/surfaces/collections-panel.json +615 -0
  330. package/src/surfaces/collections-panel.ts +168 -0
  331. package/src/surfaces/commandbar.json +241 -96
  332. package/src/surfaces/commandbar.ts +134 -99
  333. package/src/surfaces/empty-state.json +1 -1
  334. package/src/surfaces/entry-editor.json +136 -0
  335. package/src/surfaces/entry-editor.ts +21 -0
  336. package/src/surfaces/entry-inspector.json +371 -0
  337. package/src/surfaces/entry-inspector.ts +143 -0
  338. package/src/surfaces/inspector-dock.json +162 -14
  339. package/src/surfaces/inspector-dock.ts +46 -19
  340. package/src/surfaces/library-pane.json +670 -437
  341. package/src/surfaces/library-pane.ts +94 -59
  342. package/src/surfaces/media-browser.json +62 -6
  343. package/src/surfaces/media-browser.ts +15 -1
  344. package/src/surfaces/media-field.json +1 -1
  345. package/src/surfaces/media-library.json +1586 -0
  346. package/src/surfaces/media-library.ts +282 -0
  347. package/src/surfaces/media-pick-dialog.json +71 -0
  348. package/src/surfaces/media-pick-dialog.ts +132 -0
  349. package/src/surfaces/menu.ts +18 -0
  350. package/src/surfaces/pane-context.json +144 -77
  351. package/src/surfaces/pane-context.ts +24 -0
  352. package/src/surfaces/panel-deploy-checklist.json +12 -6
  353. package/src/surfaces/panel-deploy-checklist.ts +3 -1
  354. package/src/surfaces/panel-page.json +72 -2
  355. package/src/surfaces/panel-page.ts +38 -7
  356. package/src/surfaces/panel-signals.json +1 -1
  357. package/src/surfaces/panel-signals.ts +5 -5
  358. package/src/surfaces/panel-stylebook-layers.json +71 -204
  359. package/src/surfaces/panel-stylebook-layers.ts +0 -21
  360. package/src/surfaces/preferences.json +120 -48
  361. package/src/surfaces/preferences.ts +8 -0
  362. package/src/surfaces/publish-quick.json +428 -0
  363. package/src/surfaces/publish-quick.ts +165 -0
  364. package/src/surfaces/publish-workspace.json +2892 -0
  365. package/src/surfaces/publish-workspace.ts +391 -0
  366. package/src/surfaces/rail.json +1 -159
  367. package/src/surfaces/rail.ts +18 -75
  368. package/src/surfaces/schema-form.json +10 -2
  369. package/src/surfaces/schema-form.ts +2 -0
  370. package/src/surfaces/seo.json +1 -1
  371. package/src/surfaces/settings-contributed.json +5 -5
  372. package/src/surfaces/settings-contributed.ts +18 -2
  373. package/src/surfaces/settings-css-vars.json +44 -36
  374. package/src/surfaces/settings-css-vars.ts +77 -4
  375. package/src/surfaces/settings-deploy.json +2 -15
  376. package/src/surfaces/settings-deploy.ts +1 -1
  377. package/src/surfaces/settings-dialog.json +51 -0
  378. package/src/surfaces/settings-dialog.ts +169 -0
  379. package/src/surfaces/settings-overview.json +3 -3
  380. package/src/surfaces/settings-overview.ts +9 -2
  381. package/src/surfaces/settings-pane.json +269 -46
  382. package/src/surfaces/settings-pane.ts +85 -24
  383. package/src/surfaces/shell.json +2 -1
  384. package/src/surfaces/site-panel.json +1029 -0
  385. package/src/surfaces/site-panel.ts +233 -0
  386. package/src/surfaces/slash-menu.json +63 -21
  387. package/src/surfaces/slash-menu.ts +23 -0
  388. package/src/surfaces/statusbar.ts +39 -15
  389. package/src/surfaces/styles-panel.json +735 -0
  390. package/src/surfaces/styles-panel.ts +195 -0
  391. package/src/surfaces/styles-variables.json +149 -0
  392. package/src/surfaces/styles-variables.ts +145 -0
  393. package/src/surfaces/tab-strip.json +4 -4
  394. package/src/surfaces/welcome.ts +1 -1
  395. package/src/surfaces/writing-banner.json +94 -0
  396. package/src/surfaces/writing-banner.ts +80 -0
  397. package/src/tabs/bare-repeaters.ts +101 -0
  398. package/src/tabs/tab.ts +47 -7
  399. package/src/types.ts +21 -26
  400. package/src/ui/form-controls.ts +47 -8
  401. package/src/ui/layers.ts +13 -0
  402. package/src/ui/media-picker.ts +284 -40
  403. package/src/ui/regions.ts +7 -6
  404. package/src/ui/schema-form.ts +259 -27
  405. package/src/ui/virtual-window.ts +26 -1
  406. package/src/utils/base64.ts +3 -3
  407. package/src/utils/edit-display.ts +322 -67
  408. package/src/utils/local-day.ts +18 -0
  409. package/src/workspace/pane-derive.ts +4 -4
  410. package/src/workspace/session.ts +28 -7
  411. package/src/workspace/tab-workspace.ts +137 -0
  412. package/src/workspace/workspace-back.ts +189 -0
  413. package/src/workspace/workspace-home.ts +133 -0
  414. package/src/workspace/workspace-ids.ts +129 -0
  415. package/src/workspace/workspace-switch.ts +372 -0
  416. package/src/workspace/workspace.ts +125 -11
  417. package/styles/shell-frame.css +30 -7
  418. package/styles/shell-frame.json +15 -3
  419. package/dist/chunks/2020-f2gkpy8d.js +0 -4
  420. package/dist/chunks/adapter-4912g339.js +0 -4
  421. package/dist/chunks/cf-account-picker-wccaenh6.js +0 -4
  422. package/dist/chunks/cf-settings-br6105tr.js +0 -4
  423. package/dist/chunks/color-28ksk2qm.js +0 -4
  424. package/dist/chunks/components-db68vsn7.js +0 -4
  425. package/dist/chunks/content-source-1449qesq.js +0 -4
  426. package/dist/chunks/convert-to-repeater-5h457egj.js +0 -4
  427. package/dist/chunks/editor-x9jn86a7.js +0 -4
  428. package/dist/chunks/entry-commands-may24cpt.js +0 -4
  429. package/dist/chunks/extension-sections-pvr14vxr.js +0 -4
  430. package/dist/chunks/file-ops-x9v54pcj.js +0 -4
  431. package/dist/chunks/files-j3knqf0s.js +0 -4
  432. package/dist/chunks/format-host-tyre2trb.js +0 -4
  433. package/dist/chunks/fs-events-64ma9htc.js +0 -4
  434. package/dist/chunks/git-panel-84ps5dex.js +0 -4
  435. package/dist/chunks/iframe-entry-fvbk89gm.js +0 -5
  436. package/dist/chunks/iframe-host-ck6vejt5.js +0 -4
  437. package/dist/chunks/index-b8xw3vy9.js +0 -4
  438. package/dist/chunks/jsonMode-w15cmrcm.js +0 -13
  439. package/dist/chunks/jx-validate-at3zn8wa.js +0 -4
  440. package/dist/chunks/layers-h4xp1pss.js +0 -4
  441. package/dist/chunks/layers-panel-m5hw1d7g.js +0 -4
  442. package/dist/chunks/lit-html-8t8t3dnr.js +0 -4
  443. package/dist/chunks/media-picker-2cweexc5.js +0 -4
  444. package/dist/chunks/menu-ynw13y0s.js +0 -4
  445. package/dist/chunks/monaco-buffer-qzxn567r.js +0 -4
  446. package/dist/chunks/monaco-setup-gxf6656g.js +0 -4
  447. package/dist/chunks/notify-cj5zbrs2.js +0 -4
  448. package/dist/chunks/parse-b7ddhr8m.js +0 -4
  449. package/dist/chunks/platform-3dfws9js.js +0 -4
  450. package/dist/chunks/popover-jt2gxmzs.js +0 -4
  451. package/dist/chunks/publish-panel-1gvxbj21.js +0 -4
  452. package/dist/chunks/quick-search-0dajrwqg.js +0 -4
  453. package/dist/chunks/references-49qgt404.js +0 -4
  454. package/dist/chunks/right-panel-jm1bwe53.js +0 -4
  455. package/dist/chunks/section-registry-6kwc4fky.js +0 -4
  456. package/dist/chunks/studio-0rt52vpq.js +0 -5
  457. package/dist/chunks/studio-18vgbhs5.js +0 -5
  458. package/dist/chunks/studio-24mccdrj.js +0 -5
  459. package/dist/chunks/studio-2eh507zk.js +0 -9
  460. package/dist/chunks/studio-2hcbccfv.js +0 -5
  461. package/dist/chunks/studio-2jbs3rxv.js +0 -5
  462. package/dist/chunks/studio-4h8k4dw9.js +0 -5
  463. package/dist/chunks/studio-5f6n18kx.js +0 -5
  464. package/dist/chunks/studio-5gthpky6.js +0 -5
  465. package/dist/chunks/studio-6ep3js6b.js +0 -9
  466. package/dist/chunks/studio-6wkmf3wz.js +0 -9
  467. package/dist/chunks/studio-841rf3cg.js +0 -5
  468. package/dist/chunks/studio-8gmwgheg.js +0 -5
  469. package/dist/chunks/studio-8qm0ep50.js +0 -5
  470. package/dist/chunks/studio-924p1tm1.js +0 -6
  471. package/dist/chunks/studio-a3shpz9y.js +0 -5
  472. package/dist/chunks/studio-amsbaaar.js +0 -6
  473. package/dist/chunks/studio-at5spjbc.js +0 -7
  474. package/dist/chunks/studio-b2xv945e.js +0 -5
  475. package/dist/chunks/studio-bn5nkafw.js +0 -5
  476. package/dist/chunks/studio-bw6q5xjf.js +0 -9
  477. package/dist/chunks/studio-c7q0t9x1.js +0 -5
  478. package/dist/chunks/studio-camnhc96.js +0 -6
  479. package/dist/chunks/studio-cffqvnzd.js +0 -5
  480. package/dist/chunks/studio-efvfrsf8.js +0 -5
  481. package/dist/chunks/studio-er30bpcx.js +0 -5
  482. package/dist/chunks/studio-ezscgr64.js +0 -5
  483. package/dist/chunks/studio-ffrrncvz.js +0 -5
  484. package/dist/chunks/studio-fpphgn8y.js +0 -10
  485. package/dist/chunks/studio-j1kvhdjk.js +0 -4
  486. package/dist/chunks/studio-j430n16g.js +0 -7
  487. package/dist/chunks/studio-jjkg84nj.js +0 -5
  488. package/dist/chunks/studio-m0q32ars.js +0 -4
  489. package/dist/chunks/studio-m6bdst11.js +0 -5
  490. package/dist/chunks/studio-nv2cptd4.js +0 -64
  491. package/dist/chunks/studio-nwfrc98n.js +0 -5
  492. package/dist/chunks/studio-p1wgvp7r.js +0 -5
  493. package/dist/chunks/studio-pag2wncm.js +0 -5
  494. package/dist/chunks/studio-qvanvzfd.js +0 -5
  495. package/dist/chunks/studio-qwa64kt7.js +0 -5
  496. package/dist/chunks/studio-rk1zc4x3.js +0 -928
  497. package/dist/chunks/studio-se2r3ptc.js +0 -5
  498. package/dist/chunks/studio-sg2a0dh0.js +0 -5
  499. package/dist/chunks/studio-tjzjhe68.js +0 -5
  500. package/dist/chunks/studio-v2w7q8r1.js +0 -7
  501. package/dist/chunks/studio-v5vjq1h0.js +0 -4
  502. package/dist/chunks/studio-v8aga3vp.js +0 -14
  503. package/dist/chunks/studio-vfcdrfmv.js +0 -5
  504. package/dist/chunks/studio-vmfkgdjf.js +0 -5
  505. package/dist/chunks/studio-wt1816jj.js +0 -5
  506. package/dist/chunks/studio-wz73q5kq.js +0 -4
  507. package/dist/chunks/studio-y04qtxvp.js +0 -7
  508. package/dist/chunks/studio-y21g8zzg.js +0 -5
  509. package/dist/chunks/studio-y64hrt8p.js +0 -12
  510. package/dist/chunks/studio-ynn90f58.js +0 -16
  511. package/dist/chunks/studio-yxz682sx.js +0 -5
  512. package/dist/chunks/studio-zp7snvkq.js +0 -5
  513. package/dist/chunks/studio-zq4z6tm6.js +0 -5
  514. package/dist/chunks/toast-c9fn075p.js +0 -4
  515. package/dist/chunks/tsMode-sf49ee9x.js +0 -14
  516. package/dist/chunks/workspace-jtfahpee.js +0 -4
  517. package/src/panels/frontmatter-panel.ts +0 -711
  518. package/src/panels/git-panel.ts +0 -1108
  519. package/src/surfaces/doc-header.json +0 -776
  520. package/src/surfaces/doc-header.ts +0 -222
  521. package/src/surfaces/git-panel.json +0 -1880
  522. package/src/surfaces/git-panel.ts +0 -264
@@ -23,6 +23,8 @@
23
23
 
24
24
  import type { KeyScope } from "./levels";
25
25
  import type { JxPath } from "../state";
26
+ import { DEFAULT_WORKSPACE } from "../workspace/workspace-ids";
27
+ import type { WorkspaceId } from "../workspace/workspace-ids";
26
28
 
27
29
  /** PAL-derived capability keys. One `when` clause replaces a scattered `if (platform.x)`. */
28
30
  export const CAPABILITIES = [
@@ -35,6 +37,11 @@ export const CAPABILITIES = [
35
37
  /* The image editor's gate. A backend that cannot hand Studio a project file's raw bytes cannot
36
38
  decode one, so the Image mode is not offered at all rather than offered and then failing. */
37
39
  "readFileBytes",
40
+ /* The Publish family's host question (studio.md §22.8): the host can reach the Cloudflare API
41
+ (`cfApi`), so it can connect a provider, deploy and read deployments. Whether it can open a
42
+ pull request is not a key: no record is refused on it. Send for review is a destination
43
+ inside the workspace, refused by the flow with its reason (`publish/publish-changes.ts`). */
44
+ "publish",
38
45
  ] as const;
39
46
 
40
47
  export type Capability = (typeof CAPABILITIES)[number];
@@ -55,10 +62,11 @@ export type EditorKind =
55
62
  | "grid"
56
63
  | "code"
57
64
  | "diff"
58
- | "library"
59
65
  | "config"
66
+ | "tokens"
60
67
  | "entry"
61
68
  | "media"
69
+ | "home"
62
70
  | "none";
63
71
 
64
72
  /** The Canvas view axis — one control, three values (§4.2). */
@@ -90,18 +98,22 @@ const EDITOR_KIND_BY_MODE = new Map<string, EditorKind>([
90
98
  ["entry", "entry"],
91
99
  ["git-diff", "diff"],
92
100
  ["grid", "grid"],
93
- ["manage", "library"],
101
+ /* A workspace's home (`workspace/workspace-home.ts`): the surface a workspace opens on when none
102
+ of its own tabs is open. No document, no selection, nothing to paste into, so not the Canvas
103
+ key scope a mode this map did not know would fall into. */
104
+ ["content-home", "home"],
105
+ ["media-home", "home"],
106
+ ["publish-home", "home"],
94
107
  /* The Media viewer — `media/media-pane.ts`. An image, a video, a font specimen: files the studio
95
108
  can SHOW but has no document model for, which is why clicking one used to end in "No format
96
109
  class imported for …", advice that means nothing about a PNG. */
97
110
  ["media", "media"],
98
111
  ["preview", "canvas"],
99
- /* Project Settings — `settings/settings-document.ts`'s SETTINGS_MODE. A form over `project.json`,
100
- which is a configuration object and not a document tree; `stylebook` (Project Styles) is the
101
- second editor over that same document and answers `config` for the same reason. */
102
- ["settings", "config"],
103
112
  ["source", "code"],
104
113
  ["stylebook", "config"],
114
+ /* The Variables view (`style/variables-view.ts`): a form over `project.json`'s custom
115
+ properties, nothing to paste into, so the global key scope rather than the Canvas one. */
116
+ ["tokens", "tokens"],
105
117
  ]);
106
118
 
107
119
  /**
@@ -109,8 +121,7 @@ const EDITOR_KIND_BY_MODE = new Map<string, EditorKind>([
109
121
  *
110
122
  * An unknown mode reads as Canvas, and that default is only for modes STUDIO DOES NOT OWN: a format
111
123
  * declares its own list (`format.studio.modes`) and every mode declared that way is a view of the
112
- * artboard. A mode Studio itself introduces is not covered by it and belongs in the map above —
113
- * which is what `settings` was not.
124
+ * artboard. A mode Studio itself introduces is not covered by it and belongs in the map above.
114
125
  */
115
126
  /**
116
127
  * Human names for the editor kinds, so no surface prints an enum at a reader — and so two surfaces
@@ -121,13 +132,16 @@ const EDITOR_KIND_BY_MODE = new Map<string, EditorKind>([
121
132
  export const EDITOR_KIND_LABELS: Readonly<Record<EditorKind, string>> = {
122
133
  canvas: "Canvas",
123
134
  code: "Code",
124
- config: "Project Styles",
135
+ /* The Styles workspace's three views of `project.json` are named for what each one edits:
136
+ Elements (element defaults by tag, the `stylebook` editor), Variables and Code. */
137
+ config: "Elements",
125
138
  diff: "Diff",
126
139
  entry: "Entry",
127
140
  grid: "Grid",
141
+ home: "Home",
128
142
  media: "Media",
129
- library: "Library",
130
143
  none: "None",
144
+ tokens: "Variables",
131
145
  };
132
146
 
133
147
  export function editorKindForMode(mode: string): EditorKind {
@@ -164,6 +178,15 @@ export interface CommandContext {
164
178
  behind: number;
165
179
  dirtyCount: number;
166
180
  };
181
+ /**
182
+ * Which of the five workspaces is on screen (`shell.workspace`). A record or a panel whose
183
+ * surface belongs to one workspace gates on this, and every builder of a context — the live one,
184
+ * `panelContext()` and this module's empty one — has to fill it, or a predicate reads the default
185
+ * and silently never holds.
186
+ */
187
+ workspace: {
188
+ id: WorkspaceId;
189
+ };
167
190
  document: {
168
191
  open: boolean;
169
192
  dirty: boolean;
@@ -293,6 +316,7 @@ export function emptyContext(): CommandContext {
293
316
  return {
294
317
  project: { open: false, isSite: false, isRepo: false, isMultilingual: false },
295
318
  git: { ahead: 0, behind: 0, dirtyCount: 0 },
319
+ workspace: { id: DEFAULT_WORKSPACE },
296
320
  document: { open: false, dirty: false, mode: "", canUndo: false, canRedo: false },
297
321
  editor: { kind: "none" },
298
322
  canvas: { view: "design" },
@@ -319,6 +343,7 @@ export function emptyContext(): CommandContext {
319
343
  windowControls: false,
320
344
  findReferences: false,
321
345
  readFileBytes: false,
346
+ publish: false,
322
347
  },
323
348
  };
324
349
  }
@@ -50,9 +50,9 @@ export type DockId = "navigator" | "inspector" | "bottom";
50
50
  export type PaletteMode = "picker" | "files" | "commands" | "nodes" | "projects";
51
51
 
52
52
  /**
53
- * One panel, as the ⌘1–8 direct keys address it.
53
+ * One panel, as its `panel.focus.<id>` record addresses it.
54
54
  *
55
- * Structurally the part of `panels/panel-registry.ts`'s `PanelRecord` a chord needs, declared here
55
+ * Structurally the part of `panels/panel-registry.ts`'s `PanelRecord` a record needs, declared here
56
56
  * rather than imported so this module keeps its one load-bearing property: it imports no state and
57
57
  * no DOM, which is what lets the three CI checks load the command set in a bare Bun process. The
58
58
  * ROSTER arrives by injection ({@link CommandDeps.panelRoster}) from the panel registry, so there
@@ -64,30 +64,52 @@ export interface RailPanel {
64
64
  /** The panel's human name, which is also the command's title after "Show ". */
65
65
  title: string;
66
66
  /** `false` for a panel with no rail button — reachable by name, not by number. */
67
- rail?: boolean;
67
+ rail?: boolean | "developer";
68
68
  /** The panel's own visibility predicate, composed into the command's. */
69
69
  when?: (ctx: CommandContext) => boolean;
70
70
  }
71
71
 
72
- /** How many rail panels get a ⌘N: the Navigator rail (§5.1) spends four per level group. */
73
- export const RAIL_CHORD_LIMIT = 8;
72
+ /** The Inspector strip's three tabs (§6): Page · Element · Assistant. */
73
+ export type InspectorStripId = "page" | "element" | "assistant";
74
74
 
75
75
  /**
76
- * The Inspector's four tabs, in the order §6 names them — which is the order ⌘⇧1–4 follow.
76
+ * One Inspector LEAF — a view the dock can show — in the order §6 names them, which is the order
77
+ * ⌘⇧1–5 follow: Page, Element's Content · Style · Logic, then Assistant.
77
78
  *
78
- * `"assistant"` is the fourth tab, not a dock of its own (there is no assistant column, §3.1), so
79
- * it is one of `shell.ts`'s `INSPECTOR_TAB_IDS` like the other three.
79
+ * `"assistant"` is a leaf, not a dock of its own (there is no assistant column, §3.1), so it is one
80
+ * of `shell.ts`'s `INSPECTOR_TAB_IDS` like the others. `strip` says which of the three strip tabs
81
+ * hosts the leaf: the three node views share Element, behind a sub-switch, because they share one
82
+ * target.
80
83
  */
81
84
  export interface InspectorTab {
82
- /** The stored `session.ui.rightTab` value, or `"assistant"` for the assistant dock. */
85
+ /** The stored `session.ui.rightTab` value. */
83
86
  id: string;
84
87
  title: string;
88
+ strip: InspectorStripId;
85
89
  }
86
90
 
87
91
  export const INSPECTOR_TABS: readonly InspectorTab[] = [
88
- { id: "properties", title: "Content" },
89
- { id: "style", title: "Style" },
90
- { id: "events", title: "Logic" },
92
+ { id: "page", strip: "page", title: "Page" },
93
+ { id: "properties", strip: "element", title: "Content" },
94
+ { id: "style", strip: "element", title: "Style" },
95
+ { id: "events", strip: "element", title: "Logic" },
96
+ { id: "assistant", strip: "assistant", title: "Assistant" },
97
+ ];
98
+
99
+ /** One tab of the strip, and the leaves it hosts. */
100
+ export interface InspectorStripTab {
101
+ id: InspectorStripId;
102
+ title: string;
103
+ }
104
+
105
+ /**
106
+ * The strip, in order. Three tabs, under the four-per-dock cap (`studio-ui-guidelines.md` §12.2):
107
+ * Element's sub-switch is inside a tab's body and is not a dock tab. The Page tab's title is
108
+ * contextual on screen (Page, Template, Component, Entry or Document, §6); this is its name.
109
+ */
110
+ export const INSPECTOR_STRIP: readonly InspectorStripTab[] = [
111
+ { id: "page", title: "Page" },
112
+ { id: "element", title: "Element" },
91
113
  { id: "assistant", title: "Assistant" },
92
114
  ];
93
115
 
@@ -119,7 +141,8 @@ export interface CommandDeps {
119
141
  */
120
142
  newWindow: () => void | Promise<void>;
121
143
  /**
122
- * The rail's panels in rail order, then the rail-less ones — the roster ⌘1–8 is generated from.
144
+ * The rail's panels in rail order, then the rail-less ones — the roster `panel.focus.*` is
145
+ * generated from.
123
146
  *
124
147
  * Every entry is a Navigator panel: the rail is the Navigator's, and a Bottom-dock tab is
125
148
  * addressed by `view.setBottomTab` instead — one door per surface. `panels/navigator-panels.ts`'s
@@ -131,8 +154,8 @@ export interface CommandDeps {
131
154
  panelRoster: readonly RailPanel[];
132
155
  /**
133
156
  * Toggle-FOCUS a panel: reveal it and take focus, or — when it already has focus — collapse the
134
- * dock hosting it and hand focus back to the pane. Deliberately not toggle-visible: ⌘1 pressed
135
- * from the canvas must land you in Files, not close it.
157
+ * dock hosting it and hand focus back to the pane. Deliberately not toggle-visible: running it
158
+ * from the canvas must land you in the panel, not close it.
136
159
  */
137
160
  focusPanel: (panelId: string) => void;
138
161
  /** Show an Inspector tab and focus the dock. `"assistant"` addresses the assistant dock. */
@@ -305,6 +328,7 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
305
328
  keybinding: "mod+z",
306
329
  menus: ["commandbar/primary", "palette"],
307
330
  group: "1_history",
331
+ order: 1,
308
332
  when: documentOpen,
309
333
  enablement: (ctx) => ctx.document.canUndo,
310
334
  requires: "a change to undo",
@@ -319,6 +343,7 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
319
343
  keybinding: ["mod+shift+z", "mod+y"],
320
344
  menus: ["commandbar/primary", "palette"],
321
345
  group: "1_history",
346
+ order: 2,
322
347
  when: documentOpen,
323
348
  enablement: (ctx) => ctx.document.canRedo,
324
349
  requires: "a change to redo",
@@ -545,7 +570,7 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
545
570
  * The other half of multi-window, and the half that had no door.
546
571
  *
547
572
  * "Open a project ELSEWHERE" is reachable from Open Project and from Recents
548
- * (desktop.md §4.2a); "open an EMPTY window" was reachable only from the ElectroBun
573
+ * (desktop.md §4.2a); "open an EMPTY window" was reachable only from the desktop
549
574
  * launcher's native application menu — so on a launcher whose window has no menu bar,
550
575
  * `newWindow` existed on the platform and could not be run. Gated on the same capability
551
576
  * every other multi-window verb is, so a host with one window does not offer it.
@@ -601,40 +626,39 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
601
626
  }
602
627
 
603
628
  /**
604
- * ⌘1–8 — one record per panel, generated from {@link CommandDeps.panelRoster}.
629
+ * One `panel.focus.<id>` record per Navigator panel, generated from
630
+ * {@link CommandDeps.panelRoster}.
605
631
  *
606
- * Generated rather than written out eight times for the reason the whole registry exists: the rail,
607
- * the chord, the palette row and the generated shortcut sheet are then four renderings of one list.
608
- * Only the first eight get a chord; a ninth panel keeps its name and its palette row, which is the
609
- * cost studio-ui-guidelines.md §12.2 puts on chrome.
632
+ * Generated rather than written out once per panel for the reason the whole registry exists: the
633
+ * rail, the palette row and the generated command sheet are then three renderings of one list.
634
+ *
635
+ * **No chords.** ⌘1–8 used to follow the rail here. The digit row now switches WORKSPACES (⌘1–5,
636
+ * `view.setWorkspace`), because the rail is Design's alone and a chord that reached a panel from
637
+ * Publish would open a column the workspace does not draw. The records stay, in the palette and
638
+ * bindable in Preferences › Keyboard, and the rail is the pointer's way to them.
610
639
  */
611
640
  export function panelFocusCommands(deps: CommandDeps): AnyCommand[] {
612
- let chordsSpent = 0;
613
- return deps.panelRoster.map((panel) => {
614
- const command: AnyCommand = {
615
- id: `panel.focus.${panel.id}`,
616
- title: `Show ${panel.title}`,
617
- category: "View",
618
- // Application, like `view.setActivity`: revealing a panel arranges the workspace. What the
619
- // PANEL acts on is the panel record's own level, and that is `registerPanel()`'s field.
620
- level: "application",
621
- menus: ["palette"],
622
- group: "4_docks",
623
- requires: "an open project",
624
- // The panel's OWN `when` composes in, so a declared-but-unbuilt surface (Search, Problems)
625
- // Has no palette row and no live chord — the record exists, the affordance does not.
626
- when: (ctx: CommandContext) => ctx.project.open && (panel.when?.(ctx) ?? true),
627
- run: () => deps.focusPanel(panel.id),
628
- };
629
- if (panel.rail !== false && chordsSpent < RAIL_CHORD_LIMIT) {
630
- chordsSpent += 1;
631
- command.keybinding = `mod+${chordsSpent}`;
632
- }
633
- return command;
634
- });
641
+ return deps.panelRoster.map((panel): AnyCommand => ({
642
+ id: `panel.focus.${panel.id}`,
643
+ title: `Show ${panel.title}`,
644
+ category: "View",
645
+ // Application, like `view.setActivity`: revealing a panel arranges the workspace. What the
646
+ // PANEL acts on is the panel record's own level, and that is `registerPanel()`'s field.
647
+ level: "application",
648
+ menus: ["palette"],
649
+ group: "4_docks",
650
+ requires: "an open project",
651
+ // The panel's OWN `when` composes in, so a declared-but-unbuilt surface (Search, Problems)
652
+ // Has no palette row — the record exists, the affordance does not.
653
+ when: (ctx: CommandContext) => ctx.project.open && (panel.when?.(ctx) ?? true),
654
+ run: () => deps.focusPanel(panel.id),
655
+ }));
635
656
  }
636
657
 
637
- /** ⌘⇧1–4 — one record per Inspector tab, generated from {@link INSPECTOR_TABS}. */
658
+ /**
659
+ * ⌘⇧1–5 — one record per Inspector leaf, generated from {@link INSPECTOR_TABS}, so the chords
660
+ * follow the strip left to right: Page, Element › Content, Style, Logic, then Assistant.
661
+ */
638
662
  export function inspectorFocusCommands(deps: CommandDeps): AnyCommand[] {
639
663
  return INSPECTOR_TABS.map((tab, index) => {
640
664
  const command: AnyCommand = {
@@ -547,14 +547,23 @@ export function createKeymap(options: { mac?: boolean } = {}): Keymap {
547
547
  * The command id is deliberately dropped — the frame decides whether to forward, never what runs —
548
548
  * and the projection is a pure function of the keymap so the host can recompute and repost it
549
549
  * whenever a rebinding lands.
550
+ *
551
+ * `except` names commands whose chords the second realm must leave alone: a command that never
552
+ * applies to what that realm draws (`canvas/iframe-keys.ts` `HOST_ONLY_COMMANDS`) would otherwise
553
+ * have the realm cancel the keystroke's own default for nothing.
550
554
  */
551
555
  export function chordsInScopes<S extends KeyScope>(
552
556
  keymap: Keymap,
553
557
  scopes: readonly S[],
558
+ except: ReadonlySet<string> = new Set(),
554
559
  ): { chord: string; scope: S }[] {
555
560
  const seen = new Set<string>();
556
561
  const out: { chord: string; scope: S }[] = [];
557
562
  for (const entry of keymap.entries()) {
563
+ // A command that can never run on behalf of the second realm must not make it swallow a key.
564
+ if (except.has(entry.commandId)) {
565
+ continue;
566
+ }
558
567
  /* `find` rather than a `Set.has` test: the narrowed member is what makes the result carry the
559
568
  CALLER's scope union. The canvas frame's table is three scopes wide (`FRAME_KEY_SCOPES`) and
560
569
  has to stay that way across the bridge, where `SyncedChord` declares exactly those three —
@@ -176,17 +176,20 @@ export type PanelPlacement = (typeof PANEL_PLACEMENTS)[number];
176
176
  export const PANEL_PLACEMENT_MATRIX: Readonly<Record<PanelPlacement, PlacementRule>> = {
177
177
  "rail/project": {
178
178
  admits: ["project"],
179
- note: "the rail's upper group — Files, Search, Source Control, Problems",
179
+ note: "the rail's upper group — Site, and Files with the developer panels on",
180
180
  },
181
181
  "rail/document": {
182
182
  admits: ["document"],
183
- note: "the rail's lower group — Outline, Page, Data, Packages",
183
+ note: "the rail's lower group — Outline, Data, and Packages with the developer panels on",
184
184
  },
185
185
  navigator: {
186
186
  admits: ["project", "document"],
187
187
  note: "whichever level the hosted panel declares; the panel header prints it",
188
188
  },
189
- inspector: { admits: ["selection"], note: "the Inspector's tabs are selection surfaces" },
189
+ inspector: {
190
+ admits: ["document", "selection"],
191
+ note: "Page is the open document's tab, Element the selection's (§6)",
192
+ },
190
193
  "dock.bottom": { admits: ["project", "document"], note: "the panel header states which" },
191
194
  };
192
195
 
@@ -196,8 +199,11 @@ export interface PlaceablePanel {
196
199
  level: Level;
197
200
  /** The dock hosting the panel's body. */
198
201
  dock: "navigator" | "inspector" | "bottom";
199
- /** `false` for a panel with no rail button — it declares no rail-group placement. */
200
- rail?: boolean | undefined;
202
+ /**
203
+ * `false` for a panel with no rail button — it declares no rail-group placement. `"developer"` is
204
+ * a rail button only while the developer panels are shown, and it still holds its placement.
205
+ */
206
+ rail?: boolean | "developer" | undefined;
201
207
  }
202
208
 
203
209
  /** One rejected (panel, placement) pair. Shaped like {@link PlacementViolation}, keyed by panel. */
@@ -97,6 +97,7 @@ function capabilities(platform: StudioPlatform | null): CommandContext["capabili
97
97
  importSite: has("importSite"),
98
98
  openProjectInNewWindow: has("openProjectInNewWindow"),
99
99
  readFileBytes: has("readFileBytes"),
100
+ publish: has("cfApi"),
100
101
  // Multi-window is a desktop-only family; `newWindow` is the one every member implies.
101
102
  windowControls: has("newWindow"),
102
103
  };
@@ -133,6 +134,7 @@ export function createLiveContext(sources: LiveContextSources): () => CommandCon
133
134
  ctx.git.ahead = shell.git.status?.ahead ?? 0;
134
135
  ctx.git.behind = shell.git.status?.behind ?? 0;
135
136
  ctx.git.dirtyCount = shell.git.status?.files.length ?? 0;
137
+ ctx.workspace.id = shell.workspace;
136
138
 
137
139
  ctx.document.open = tab !== null;
138
140
  // Typing still in a source buffer is unsaved work too, though the document has not seen it.
@@ -81,6 +81,12 @@ export interface Command<A = void> {
81
81
  menus?: readonly Placement[];
82
82
  /** Menu ordering key: "1_clipboard", "3_structure", "9_danger". */
83
83
  group?: string;
84
+ /**
85
+ * Position within its {@link Command.group}, lower first. A command without one follows the
86
+ * ordered commands of its group, by title. A group whose members have a reading order of their
87
+ * own (Undo before Redo) states it here, because the title is an accident of the language.
88
+ */
89
+ order?: number;
84
90
  /**
85
91
  * How the effect is undone. Also the LEDGER SCOPE of a bridged write:
86
92
  * `services/ai-command-tools.ts` records one "Changed N files" entry per path a projected run
@@ -371,7 +377,10 @@ export function createCommandRegistry(options: CommandRegistryOptions): CommandR
371
377
  (command.menus ?? ["palette"]).includes(placement) && visibleWith(command, ctx),
372
378
  )
373
379
  .toSorted(
374
- (a, b) => (a.group ?? "").localeCompare(b.group ?? "") || a.title.localeCompare(b.title),
380
+ (a, b) =>
381
+ (a.group ?? "").localeCompare(b.group ?? "") ||
382
+ (a.order ?? Number.POSITIVE_INFINITY) - (b.order ?? Number.POSITIVE_INFINITY) ||
383
+ a.title.localeCompare(b.title),
375
384
  );
376
385
  },
377
386
  isVisible(id) {
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * Collection-match — the ONE answer to "which content collection owns this path".
3
3
  *
4
- * Three matchers already existed and disagreed: `utils/studio-utils.ts`'s `findContentTypeSchema`,
4
+ * Three matchers existed and disagreed: `utils/studio-utils.ts`'s `findContentTypeSchema`,
5
5
  * `grid/sources/content-source.ts`'s `collectionInfo` and `browse/library-model.ts`'s
6
- * `contentTypeFor`. Each was right about the question it was written for and wrong about the
7
- * others', which was tolerable while the consumers were a form and a grid. It stopped being
8
- * tolerable when the Files tree began asking, because a mismatch there does not draw the wrong
9
- * field — it CONSTRAINS or REROUTES a creation, and both are wrong answers the author cannot see.
6
+ * `contentTypeFor` (since deleted: the Content workspace asks this module instead). Each was right
7
+ * about the question it was written for and wrong about the others', which was tolerable while the
8
+ * consumers were a form and a grid. It stopped being tolerable when the Files tree began asking,
9
+ * because a mismatch there does not draw the wrong field — it CONSTRAINS or REROUTES a creation,
10
+ * and both are wrong answers the author cannot see.
10
11
  *
11
12
  * Four things this states that no predecessor did:
12
13
  *