@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
@@ -15,8 +15,8 @@
15
15
  * **This flow fails, and until now it failed silently.** `https://github.com/login/device/code`
16
16
  * sends no `Access-Control-Allow-Origin`, so a browser cannot call it: in Studio-in-a-browser the
17
17
  * very first request rejects with a bare `TypeError`. That rejection used to become a thrown
18
- * `Error` out of {@link authenticateGithub}, into `void createGithubRepository(…)` in
19
- * `panels/git-panel.ts`, and from there into an unhandled promise rejection — the user clicked
18
+ * `Error` out of {@link authenticateGithub}, into `void createGithubRepository(…)` in the Source
19
+ * Control panel of the time, and from there into an unhandled promise rejection — the user clicked
20
20
  * "Create GitHub repository" and the app did nothing at all, forever, with no message anywhere.
21
21
  *
22
22
  * Three failures now reach a surface, each as the kind of record §16 says it is:
@@ -59,8 +59,14 @@ import { errorMessage } from "@jxsuite/schema/parse";
59
59
  import { notify } from "../services/notify";
60
60
  import { layerHost } from "../ui/layers";
61
61
  import { openGithubAuthSurface } from "../surfaces/github-auth";
62
- import type { GithubAuthSurfaceHandle } from "../surfaces/github-auth";
63
- import { getGithubToken, nativeAuth, setNativeToken, STORAGE_KEY } from "./github-auth-status";
62
+ import {
63
+ getGithubToken,
64
+ GITHUB_OAUTH_CLIENT_ID,
65
+ nativeAuth,
66
+ setNativeToken,
67
+ STORAGE_KEY,
68
+ } from "./github-auth-status";
69
+ import type { DialogLayerHandle } from "../ui/surface";
64
70
 
65
71
  // Every other caller in Studio still reaches these through this module.
66
72
  export {
@@ -71,8 +77,6 @@ export {
71
77
  hydrateGithubToken,
72
78
  } from "./github-auth-status";
73
79
 
74
- const CLIENT_ID = "Ov23liYVlMFpgjOEPXJH";
75
-
76
80
  /** One key for the whole sign-in, so a second attempt REPLACES the first report. */
77
81
  const NOTIFY_KEY = "github.auth";
78
82
 
@@ -108,10 +112,10 @@ interface TokenResponse {
108
112
  }
109
113
 
110
114
  /** The request never completed — a Problem, with the one sentence that covers both causes. */
111
- function reportUnreachable(error: unknown): void {
115
+ function reportUnreachable(cause: unknown): void {
112
116
  notify.error("Could not reach GitHub to sign in.", {
113
117
  action: RETRY,
114
- detail: `${UNREACHABLE_DETAIL}\n\n${errorMessage(error)}`,
118
+ detail: `${UNREACHABLE_DETAIL}\n\n${errorMessage(cause)}`,
115
119
  key: NOTIFY_KEY,
116
120
  source: SOURCE,
117
121
  });
@@ -132,7 +136,7 @@ async function requestDeviceCode(): Promise<DeviceCodeResponse | null> {
132
136
  let codeRes: Response;
133
137
  try {
134
138
  codeRes = await fetch("https://github.com/login/device/code", {
135
- body: JSON.stringify({ client_id: CLIENT_ID, scope: "repo" }),
139
+ body: JSON.stringify({ client_id: GITHUB_OAUTH_CLIENT_ID, scope: "repo" }),
136
140
  headers: {
137
141
  Accept: "application/json",
138
142
  "Content-Type": "application/json",
@@ -151,6 +155,9 @@ async function requestDeviceCode(): Promise<DeviceCodeResponse | null> {
151
155
  );
152
156
  return null;
153
157
  }
158
+ /* SAFETY: a 2xx from GitHub's device-code endpoint (checked just above) is the JSON object
159
+ RFC 8628 §3.2 defines — `device_code`, `user_code`, `verification_uri` and an optional
160
+ `interval` — which is exactly what `DeviceCodeResponse` declares. */
154
161
  return (await codeRes.json()) as DeviceCodeResponse;
155
162
  }
156
163
 
@@ -247,7 +254,7 @@ export async function authenticateGithub() {
247
254
  try {
248
255
  const tokenRes = await fetch("https://github.com/login/oauth/access_token", {
249
256
  body: JSON.stringify({
250
- client_id: CLIENT_ID,
257
+ client_id: GITHUB_OAUTH_CLIENT_ID,
251
258
  device_code,
252
259
  grant_type: "urn:ietf:params:oauth:grant-type:device_code",
253
260
  }),
@@ -257,6 +264,9 @@ export async function authenticateGithub() {
257
264
  },
258
265
  method: "POST",
259
266
  });
267
+ /* SAFETY: GitHub's token endpoint answers every poll with a JSON object carrying either an
268
+ `access_token` (RFC 6749 §5.1) or an `error` code (RFC 8628 §3.5); `TokenResponse` makes
269
+ Both optional, and every branch below reads them as possibly absent. */
260
270
  const tokenData = (await tokenRes.json()) as TokenResponse;
261
271
  failures = 0;
262
272
 
@@ -303,7 +313,7 @@ export async function authenticateGithub() {
303
313
  * the surface existed would find a binding that is not initialised yet — which a zero-second
304
314
  * device interval makes reachable rather than theoretical.
305
315
  */
306
- const handle: GithubAuthSurfaceHandle = openGithubAuthSurface({
316
+ const handle: DialogLayerHandle = openGithubAuthSurface({
307
317
  layer: layerHost("dialog"),
308
318
  onCancel: () => {
309
319
  takeDown();
@@ -31,7 +31,8 @@ import { authenticateGithub } from "./github-auth";
31
31
  import { beginActivity } from "../panels/activity-panel";
32
32
  import { getPlatform } from "../platform";
33
33
  import { notify } from "../services/notify";
34
- import type { GithubPublishSurfaceHandle, RepoOptions } from "../surfaces/github-publish";
34
+ import type { RepoOptions } from "../surfaces/github-publish";
35
+ import type { DialogLayerHandle } from "../ui/surface";
35
36
 
36
37
  interface GithubErrorResponse {
37
38
  errors?: { message?: string }[];
@@ -77,7 +78,7 @@ function askForRepoOptions(projectName: string): Promise<RepoOptions | null> {
77
78
  answered = true;
78
79
  resolve(value);
79
80
  };
80
- const handle: GithubPublishSurfaceHandle = openGithubPublishSurface({
81
+ const handle: DialogLayerHandle = openGithubPublishSurface({
81
82
  layer: layerHost("dialog"),
82
83
  name: projectName,
83
84
  onCancel: () => {
@@ -125,25 +126,24 @@ export async function createGithubRepository({ projectName }: { projectName: str
125
126
  });
126
127
 
127
128
  activity.step(REPO_STEPS[0]);
128
- const createRes = await fetch("https://api.github.com/user/repos", {
129
- body: JSON.stringify({
130
- auto_init: false,
131
- description: repoOpts.description,
132
- name: repoOpts.name,
133
- private: repoOpts.isPrivate,
134
- }),
135
- headers: {
136
- Accept: "application/vnd.github+json",
137
- Authorization: `Bearer ${token}`,
138
- "Content-Type": "application/json",
139
- },
140
- method: "POST",
141
- }).catch((error: unknown) => {
129
+ let createRes: Response;
130
+ try {
131
+ createRes = await fetch("https://api.github.com/user/repos", {
132
+ body: JSON.stringify({
133
+ auto_init: false,
134
+ description: repoOpts.description,
135
+ name: repoOpts.name,
136
+ private: repoOpts.isPrivate,
137
+ }),
138
+ headers: {
139
+ Accept: "application/vnd.github+json",
140
+ Authorization: `Bearer ${token}`,
141
+ "Content-Type": "application/json",
142
+ },
143
+ method: "POST",
144
+ });
145
+ } catch (error) {
142
146
  activity.log(errorMessage(error));
143
- return null;
144
- });
145
-
146
- if (!createRes) {
147
147
  activity.fail("Could not reach GitHub to create the repository.", {
148
148
  action: "git.createGithubRepository",
149
149
  });
@@ -151,6 +151,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
151
151
  }
152
152
 
153
153
  if (!createRes.ok) {
154
+ /* SAFETY: GitHub's REST API answers a failed request with a JSON body carrying `message` and,
155
+ For a validation failure, an `errors` array; both are optional here and read with fallbacks. */
154
156
  const err = (await createRes.json()) as GithubErrorResponse;
155
157
  activity.log(err.errors?.[0]?.message || err.message || `GitHub answered ${createRes.status}.`);
156
158
  activity.fail("Could not create the GitHub repository.", {
@@ -159,6 +161,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
159
161
  return false;
160
162
  }
161
163
 
164
+ /* SAFETY: `createRes.ok` was checked above, and a successful `POST /user/repos` answers with the
165
+ Full repository object, of which `clone_url` and `html_url` are required members. */
162
166
  const repo = (await createRes.json()) as GithubRepoResponse;
163
167
  activity.log(`Created ${repo.html_url}`);
164
168
  const platform = getPlatform();
@@ -171,7 +175,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
171
175
  // Surfaced as a push failure describing the push.
172
176
  activity.log(errorMessage(error));
173
177
  activity.fail("The repository was created, but the remote could not be added.", {
174
- action: "panel.focus.git",
178
+ action: "view.setWorkspace",
179
+ actionArgs: { workspace: "publish" },
175
180
  });
176
181
  return false;
177
182
  }
@@ -187,8 +192,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
187
192
  return false;
188
193
  }
189
194
 
190
- // Lazy import breaks the github-publish ↔ git-panel module cycle
191
- const { refreshGitStatus } = await import("../panels/git-panel");
195
+ // Lazy import breaks the github-publish ↔ source-control module cycle
196
+ const { refreshGitStatus } = await import("../publish/source-control");
192
197
  await refreshGitStatus();
193
198
  activity.done(repo.html_url);
194
199
  notify.success(`Repository created: ${repo.html_url}`, { key: "github.repo" });
@@ -58,15 +58,18 @@ import { live } from "lit-html/directives/live.js";
58
58
  import { cellToText, coerceCellInput } from "./schema-columns";
59
59
  import type { GridCellValue, GridColumn } from "./grid-source";
60
60
 
61
- /** The subset of Tabulator's CellComponent the editors/formatters touch. */
61
+ /**
62
+ * The subset of Tabulator's CellComponent the editors/formatters touch. A cell's value is a
63
+ * {@link GridCellValue}: the grid's row data is the grid source's rows, which hold nothing else.
64
+ */
62
65
  export interface CellLike {
63
- getValue: () => unknown;
66
+ getValue: () => GridCellValue;
64
67
  }
65
68
 
66
69
  export type CellEditorFn = (
67
70
  cell: CellLike,
68
71
  onRendered: (fn: () => void) => void,
69
- success: (value: unknown) => void,
72
+ success: (value: GridCellValue) => void,
70
73
  cancel: () => void,
71
74
  ) => HTMLElement;
72
75
 
@@ -75,6 +78,17 @@ export type CellFormatterFn = (cell: CellLike) => HTMLElement;
75
78
  /** Detached-host factory — grid-view owns the one sanctioned document.createElement. */
76
79
  export type HostFactory = (className: string) => HTMLElement;
77
80
 
81
+ /**
82
+ * The `<input>` a listener in this file is bound on.
83
+ *
84
+ * Every input listener here sits on the `<input>` its own template renders, and an input has no
85
+ * children, so a keydown, change or blur it hears was dispatched at the input itself.
86
+ */
87
+ function inputOf(e: Event): HTMLInputElement {
88
+ // SAFETY: the listener is bound on an `<input>` (above), and a void element is its events' target.
89
+ return e.target as HTMLInputElement;
90
+ }
91
+
78
92
  /** Commit/cancel wiring shared by every text-ish editor. */
79
93
  function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: string): CellEditorFn {
80
94
  return (cell, onRendered, success, cancel) => {
@@ -94,8 +108,8 @@ function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: strin
94
108
  };
95
109
  const initial =
96
110
  column.kind === "date"
97
- ? cellToText(cell.getValue() as GridCellValue).slice(0, 10)
98
- : cellToText(cell.getValue() as GridCellValue);
111
+ ? cellToText(cell.getValue()).slice(0, 10)
112
+ : cellToText(cell.getValue());
99
113
  render(
100
114
  html`<input
101
115
  class="jx-grid-input"
@@ -103,12 +117,12 @@ function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: strin
103
117
  .value=${live(initial)}
104
118
  @keydown=${(e: KeyboardEvent) => {
105
119
  if (e.key === "Enter") {
106
- commit((e.target as HTMLInputElement).value);
120
+ commit(inputOf(e).value);
107
121
  } else if (e.key === "Escape") {
108
122
  abort();
109
123
  }
110
124
  }}
111
- @blur=${(e: Event) => commit((e.target as HTMLInputElement).value)}
125
+ @blur=${(e: Event) => commit(inputOf(e).value)}
112
126
  />`,
113
127
  host,
114
128
  );
@@ -133,7 +147,7 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
133
147
  @change=${(e: Event) => {
134
148
  if (!done) {
135
149
  done = true;
136
- success((e.target as HTMLInputElement).checked);
150
+ success(inputOf(e).checked);
137
151
  }
138
152
  }}
139
153
  @keydown=${(e: KeyboardEvent) => {
@@ -142,13 +156,13 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
142
156
  cancel();
143
157
  } else if (e.key === "Enter" && !done) {
144
158
  done = true;
145
- success((e.target as HTMLInputElement).checked);
159
+ success(inputOf(e).checked);
146
160
  }
147
161
  }}
148
162
  @blur=${(e: Event) => {
149
163
  if (!done) {
150
164
  done = true;
151
- success((e.target as HTMLInputElement).checked);
165
+ success(inputOf(e).checked);
152
166
  }
153
167
  }}
154
168
  />`,
@@ -160,19 +174,19 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
160
174
  }
161
175
 
162
176
  function selectEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
163
- const options = Array.isArray(column.schema?.enum)
164
- ? (column.schema.enum as unknown[]).map(String)
165
- : [];
177
+ const options = Array.isArray(column.schema?.enum) ? column.schema.enum.map(String) : [];
166
178
  return (cell, onRendered, success, cancel) => {
167
179
  const host = makeHost("jx-grid-editor");
168
180
  let done = false;
169
- const current = cellToText(cell.getValue() as GridCellValue);
181
+ const current = cellToText(cell.getValue());
170
182
  render(
171
183
  html`<select
172
184
  class="jx-grid-select"
173
185
  @change=${(e: Event) => {
174
186
  if (!done) {
175
187
  done = true;
188
+ // SAFETY: this listener is bound on the `<select>` rendered here, and `change` is
189
+ // Dispatched at the select itself, never at one of its options.
176
190
  const { value } = e.target as HTMLSelectElement;
177
191
  success(value === "" ? null : value);
178
192
  }
@@ -235,26 +249,27 @@ function pillEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
235
249
  render(
236
250
  html`<span class="jx-grid-pills">
237
251
  ${chips.map(
238
- (chip, i) => html`<span class="jx-grid-chip"
239
- >${chip}<button
240
- class="jx-grid-chip-x"
241
- title="Remove"
242
- @mousedown=${(e: Event) => e.preventDefault()}
243
- @click=${() => {
244
- chips.splice(i, 1);
245
- doRender();
246
- inputEl()?.focus();
247
- }}
248
- >
249
- ×
250
- </button></span
251
- >`,
252
+ (chip, i) =>
253
+ html`<span class="jx-grid-chip"
254
+ >${chip}<button
255
+ class="jx-grid-chip-x"
256
+ title="Remove"
257
+ @mousedown=${(e: Event) => e.preventDefault()}
258
+ @click=${() => {
259
+ chips.splice(i, 1);
260
+ doRender();
261
+ inputEl()?.focus();
262
+ }}
263
+ >
264
+ ×
265
+ </button></span
266
+ >`,
252
267
  )}
253
268
  <input
254
269
  class="jx-grid-pill-input"
255
270
  placeholder=${chips.length === 0 ? "add…" : ""}
256
271
  @keydown=${(e: KeyboardEvent) => {
257
- const input = e.target as HTMLInputElement;
272
+ const input = inputOf(e);
258
273
  if (e.key === "Enter" || e.key === ",") {
259
274
  e.preventDefault();
260
275
  if (addFromInput(input)) {
@@ -272,7 +287,7 @@ function pillEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
272
287
  }
273
288
  }}
274
289
  @blur=${(e: Event) => {
275
- addFromInput(e.target as HTMLInputElement);
290
+ addFromInput(inputOf(e));
276
291
  finish([...chips]);
277
292
  }}
278
293
  />
@@ -317,7 +332,7 @@ export function editorForColumn(
317
332
  /** Formatter factory — plain-text projection rendered as a real element (innerHTML-safe). */
318
333
  export function formatterForColumn(column: GridColumn, makeHost: HostFactory): CellFormatterFn {
319
334
  return (cell) => {
320
- const value = cell.getValue() as GridCellValue;
335
+ const value = cell.getValue();
321
336
  const host = makeHost(`jx-grid-cell-content jx-grid-kind-${column.kind}`);
322
337
  if (column.kind === "boolean") {
323
338
  render(html`${value === true ? "✓" : ""}`, host);
@@ -12,6 +12,7 @@
12
12
  * through the panel's island seam (specs/studio-ui-guidelines.md §9.4) — the box is drawn by one
13
13
  * document and filled by another, and nothing in this file renders anything.
14
14
  */
15
+ import { isString } from "@jxsuite/schema/guards";
15
16
  import { openGridCellSurface } from "../surfaces/grid-cell";
16
17
  import { mountMediaPicker } from "../ui/media-picker";
17
18
  import { listCollectionEntryIds } from "./sources/content-source";
@@ -25,8 +26,9 @@ export function hasPopoverEditor(column: GridColumn): boolean {
25
26
 
26
27
  /** Target content-type name of a relationship column (`#/content/<name>` on the schema). */
27
28
  export function referenceTargetType(column: GridColumn): string | null {
28
- const ref = (column.schema as { $ref?: string } | undefined)?.$ref;
29
- if (typeof ref !== "string" || !ref.startsWith("#/content/")) {
29
+ // The schema is the project's own JSON, so `$ref` is checked rather than trusted to be a string.
30
+ const ref = column.schema?.$ref;
31
+ if (!isString(ref) || !ref.startsWith("#/content/")) {
30
32
  return null;
31
33
  }
32
34
  return ref.slice("#/content/".length);
@@ -47,7 +49,7 @@ export interface CellPopoverArgs {
47
49
  * The clamp is the panel's own width and a floor for its height, because a cell near the right edge
48
50
  * of a wide grid is exactly where a relationship column tends to be.
49
51
  */
50
- function placement(anchor: CellPopoverArgs["anchor"]): { x: number; y: number } {
52
+ function placement(anchor: CellPopoverArgs["anchor"]) {
51
53
  return {
52
54
  x: Math.max(4, Math.min(anchor.left, window.innerWidth - 340)),
53
55
  y: Math.max(4, Math.min(anchor.bottom + 2, window.innerHeight - 200)),
@@ -92,15 +92,16 @@ export function createEditBuffer(opts: EditBufferOptions): EditBuffer {
92
92
  const coalesceMs = opts.coalesceMs ?? 800;
93
93
  const now = opts.now ?? (() => Date.now());
94
94
 
95
- const state: EditBufferState = reactive({
96
- deletes: new Set<string>(),
97
- errors: new Map<string, Map<string, string>>(),
98
- inserts: new Map<string, Record<string, GridCellValue>>(),
99
- pending: new Map<string, Map<string, { value: GridCellValue }>>(),
100
- redoStack: [] as BufferOp[],
101
- stale: new Set<string>(),
102
- undoStack: [] as BufferOp[],
103
- }) as EditBufferState;
95
+ const initial: EditBufferState = {
96
+ deletes: new Set(),
97
+ errors: new Map(),
98
+ inserts: new Map(),
99
+ pending: new Map(),
100
+ redoStack: [],
101
+ stale: new Set(),
102
+ undoStack: [],
103
+ };
104
+ const state: EditBufferState = reactive(initial);
104
105
 
105
106
  let groupOps: BufferOp[] | null = null;
106
107
 
@@ -19,6 +19,7 @@ import { isRecentLocal } from "../files/fs-events";
19
19
  import { showConfirmDialog } from "../ui/layers";
20
20
  import { showProgressModal } from "../ui/progress-modal";
21
21
  import { errorMessage } from "@jxsuite/schema/parse";
22
+ import { isNonNullObject, isNumber, isString } from "@jxsuite/schema/guards";
22
23
  import { createEditBuffer } from "./edit-buffer";
23
24
  import { cellToText } from "./schema-columns";
24
25
  import type { EditBuffer } from "./edit-buffer";
@@ -111,25 +112,26 @@ export interface GridController {
111
112
  /** Row-object key carrying the grid row identity through the engine. */
112
113
  export const ROW_KEY_FIELD = "__key";
113
114
 
114
- const _controllers = new WeakMap<object, GridController>();
115
+ const _controllers = new WeakMap<Tab, GridController>();
115
116
 
116
117
  /** The grid controller for a tab, if it is a grid tab. */
117
118
  export function getGridController(tab: Tab | null): GridController | null {
118
- return tab ? (_controllers.get(toRaw(tab as unknown as object)) ?? null) : null;
119
+ return tab ? (_controllers.get(toRaw(tab)) ?? null) : null;
119
120
  }
120
121
 
121
122
  /** Create and register the controller for a grid tab. One per tab; lives in the tab's scope. */
122
123
  export function createGridController(tab: Tab, source: GridSource): GridController {
123
- const state: GridControllerState = reactive({
124
- columns: [] as GridColumn[],
125
- error: null as string | null,
126
- grouping: null as string | null,
124
+ const initial: GridControllerState = {
125
+ columns: [],
126
+ error: null,
127
+ grouping: null,
127
128
  loading: false,
128
- query: {} as GridQuery,
129
- rows: [] as GridRow[],
129
+ query: {},
130
+ rows: [],
130
131
  saving: false,
131
132
  total: 0,
132
- }) as GridControllerState;
133
+ };
134
+ const state: GridControllerState = reactive(initial);
133
135
 
134
136
  let rowByKey = new Map<string, GridRow>();
135
137
  const indexRows = (rows: GridRow[]) => {
@@ -142,9 +144,13 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
142
144
 
143
145
  const reloadRows = async () => {
144
146
  const result = await source.rows(state.query);
147
+ /* Index BEFORE the rows are published. The index is not reactive, and assigning `state.rows`
148
+ runs the effects that read it at once: a record's entry form (`content/record-entry.ts`)
149
+ resolves its row key from the new rows and reads that row's cells through the baseline,
150
+ which with the index still empty drew every field blank until something else re-ran it. */
151
+ indexRows(result.rows);
145
152
  state.rows = result.rows;
146
153
  state.total = result.total;
147
- indexRows(result.rows);
148
154
  };
149
155
 
150
156
  /** Missing required cells block the save (marked as row/cell errors, like a failed commit). */
@@ -181,7 +187,7 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
181
187
 
182
188
  const compareCells = (a: GridCellValue, b: GridCellValue, kind: GridColumnKind | undefined) => {
183
189
  if (kind === "number") {
184
- return (typeof a === "number" ? a : 0) - (typeof b === "number" ? b : 0);
190
+ return (isNumber(a) ? a : 0) - (isNumber(b) ? b : 0);
185
191
  }
186
192
  if (kind === "boolean") {
187
193
  return (a === true ? 1 : 0) - (b === true ? 1 : 0);
@@ -280,7 +286,7 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
280
286
  }
281
287
  for (const column of textColumns) {
282
288
  const value = buffer.effectiveValue(rowKey, column.field);
283
- if (typeof value === "string" && value.includes(find)) {
289
+ if (isString(value) && value.includes(find)) {
284
290
  buffer.setCell(rowKey, column.field, value.replaceAll(find, replace));
285
291
  changed += 1;
286
292
  }
@@ -296,17 +302,13 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
296
302
  effectiveRows() {
297
303
  // Detach values from reactive proxies — the grid engine must never hold live proxies.
298
304
  const plain = (value: GridCellValue): GridCellValue =>
299
- Array.isArray(value)
300
- ? [...value]
301
- : value !== null && typeof value === "object"
302
- ? { $ref: value.$ref }
303
- : value;
304
- const rowObject = (key: string) => {
305
- const cells: Record<string, GridCellValue> = { [ROW_KEY_FIELD]: key };
305
+ Array.isArray(value) ? [...value] : isNonNullObject(value) ? { $ref: value.$ref } : value;
306
+ const rowObject = (key: string): Record<string, GridCellValue> => {
307
+ const cells: [field: string, value: GridCellValue][] = [[ROW_KEY_FIELD, key]];
306
308
  for (const column of state.columns) {
307
- cells[column.field] = plain(buffer.effectiveValue(key, column.field));
309
+ cells.push([column.field, plain(buffer.effectiveValue(key, column.field))]);
308
310
  }
309
- return cells;
311
+ return Object.fromEntries(cells);
310
312
  };
311
313
  const rows = orderedKeys().map((key) => rowObject(key));
312
314
  for (const [tempKey] of buffer.state.inserts) {
@@ -547,11 +549,11 @@ export function createGridController(tab: Tab, source: GridSource): GridControll
547
549
 
548
550
  onScopeDispose(() => {
549
551
  setHistoryDelegate(tab, null);
550
- _controllers.delete(toRaw(tab as unknown as object));
552
+ _controllers.delete(toRaw(tab));
551
553
  source.dispose?.();
552
554
  });
553
555
  });
554
556
 
555
- _controllers.set(toRaw(tab as unknown as object), controller);
557
+ _controllers.set(toRaw(tab), controller);
556
558
  return controller;
557
559
  }
@@ -23,6 +23,7 @@
23
23
  * layout keep their relative position at the end; saved fields that no longer exist are ignored —
24
24
  * schemas drift).
25
25
  */
26
+ import { isNonNullObject, isString } from "@jxsuite/schema/guards";
26
27
 
27
28
  /** One sort, as a saved view records it. The grid is single-key sorted; a second key is not saved. */
28
29
  export interface GridSortSpec {
@@ -70,7 +71,7 @@ const STORAGE_PREFIX = "jx-grid-layout:";
70
71
 
71
72
  function storage(): Storage | null {
72
73
  try {
73
- return globalThis.localStorage ?? null;
74
+ return typeof localStorage === "undefined" ? null : localStorage;
74
75
  } catch {
75
76
  return null; // Storage disabled (privacy mode) — layouts just don't persist.
76
77
  }
@@ -83,8 +84,11 @@ function readRecord(gridId: string): GridLayoutRecord | null {
83
84
  return null;
84
85
  }
85
86
  try {
86
- const parsed = JSON.parse(raw) as GridLayoutRecord;
87
- return typeof parsed === "object" && parsed !== null ? parsed : null;
87
+ const parsed: unknown = JSON.parse(raw);
88
+ /* SAFETY: this key is written only by `writeRecord`, which stores a serialized
89
+ GridLayoutRecord, and every reader treats each field as possibly absent (`?.`, `??`, and
90
+ `listSavedViews` drops any entry that is not a named view). A non-object is refused here. */
91
+ return isNonNullObject(parsed) ? (parsed as GridLayoutRecord) : null;
88
92
  } catch {
89
93
  return null;
90
94
  }
@@ -153,7 +157,11 @@ export function resetGridLayout(gridId: string): void {
153
157
  if (!record) {
154
158
  return;
155
159
  }
156
- writeRecord(gridId, { active: null, ...(record.views ? { views: record.views } : {}) });
160
+ const next: GridLayoutRecord = { active: null };
161
+ if (record.views) {
162
+ next.views = record.views;
163
+ }
164
+ writeRecord(gridId, next);
157
165
  }
158
166
 
159
167
  // ─── Named views ──────────────────────────────────────────────────────────────
@@ -161,7 +169,15 @@ export function resetGridLayout(gridId: string): void {
161
169
  /** The named views for a grid id, in save order. */
162
170
  export function listSavedViews(gridId: string): SavedGridView[] {
163
171
  const views = readRecord(gridId)?.views;
164
- return Array.isArray(views) ? views.filter((view) => typeof view?.name === "string") : [];
172
+ return Array.isArray(views) ? views.filter((view) => isSavedGridView(view)) : [];
173
+ }
174
+
175
+ /**
176
+ * Whether a stored `views` entry is a named view. Storage outlives the code that wrote it, so an
177
+ * entry without a string `name` (null, a primitive, an older shape) is skipped rather than shown.
178
+ */
179
+ function isSavedGridView(view: unknown): view is SavedGridView {
180
+ return isNonNullObject(view) && "name" in view && isString(view.name);
165
181
  }
166
182
 
167
183
  /** The name of the view last applied to this grid, or null when the layout is unnamed. */
@@ -19,17 +19,13 @@ import {
19
19
  createPagesSource,
20
20
  } from "./sources/content-source";
21
21
  import { createConnectorSource } from "./sources/connector-source";
22
- import { makeGridTabId, parseGridTabId } from "./grid-source";
23
- import { libraryTabId } from "../browse/library-source";
22
+ import { GRID_STUB_DOCUMENT, makeGridTabId, parseGridTabId } from "./grid-source";
24
23
  import { argsSchema, optionalStringArg, stringArg, stringProperty } from "../commands/command-args";
25
24
  import type { GridSource } from "./grid-source";
26
25
  import type { GridOpenSurfaceHandle, GridSourceGroup } from "../surfaces/grid-open";
27
26
  import type { Tab } from "../tabs/tab";
28
27
  import type { AnyCommand, CommandRegistry } from "../commands/registry";
29
28
 
30
- /** Placeholder document for grid tabs — the grid never reads it; save routes to the controller. */
31
- const GRID_STUB_DOCUMENT = { children: [], tagName: "div" };
32
-
33
29
  /**
34
30
  * Open (or activate) a `.csv` file as a grid tab.
35
31
  *
@@ -102,32 +98,6 @@ export function openCollectionGrid(typeName: string): Tab {
102
98
  return openVirtualGridTab(createCollectionSource(typeName));
103
99
  }
104
100
 
105
- /**
106
- * Open (or activate) the Library.
107
- *
108
- * A real tab, in the primary pane, with `manage` as its only mode — `commands/context.ts` maps that
109
- * to the `library` editor kind, so the status bar and the pane context bar can name what is on
110
- * screen. It is opened here rather than in `browse/` because this is the module that knows how a
111
- * virtual tab is made; the pane itself resolves its own source and its own view state.
112
- *
113
- * Idempotent by construction, which is what lets a shot say "the Library is open" without caring
114
- * whether an earlier step opened it.
115
- */
116
- export function openLibraryTab(): Tab {
117
- const id = libraryTabId();
118
- const existing = workspace.tabs.get(id);
119
- if (existing) {
120
- activateTab(id);
121
- return existing;
122
- }
123
- return openTab({
124
- capabilities: { modes: ["manage"] },
125
- document: structuredClone(GRID_STUB_DOCUMENT),
126
- documentPath: null,
127
- id,
128
- });
129
- }
130
-
131
101
  /** Open (or activate) the pages metadata grid. */
132
102
  export function openPagesGrid(): Tab {
133
103
  const id = makeGridTabId({ kind: "pages" });
@@ -187,14 +157,14 @@ function sourceGroups(
187
157
  state: "listed",
188
158
  title: "Project",
189
159
  },
190
- ...connections.map((conn) => ({
160
+ ...connections.map((conn): GridSourceGroup => ({
191
161
  emptyMessage: "No tables — push a schema first.",
192
162
  key: `data:${conn.name}`,
193
163
  rows: conn.tables.map((table) => ({
194
164
  id: makeGridTabId({ connection: conn.name, kind: "data", table }),
195
165
  label: table,
196
166
  })),
197
- state: (conn.tables.length === 0 ? "empty" : "listed") as "empty" | "listed",
167
+ state: conn.tables.length === 0 ? "empty" : "listed",
198
168
  title: `Data · ${conn.name}`,
199
169
  })),
200
170
  ];