@jxsuite/studio 6.1.1 → 6.1.2

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 (637) hide show
  1. package/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
  2. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  3. package/dist/chunks/adapter-4912g339.js +4 -0
  4. package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
  5. package/dist/chunks/cf-settings-br6105tr.js +4 -0
  6. package/dist/chunks/color-28ksk2qm.js +4 -0
  7. package/dist/chunks/color-area-0fj8a4ga.js +4 -0
  8. package/dist/chunks/color-field-xch8kx2g.js +4 -0
  9. package/dist/chunks/color-slider-jxd8v350.js +4 -0
  10. package/dist/chunks/combobox-p0efwjke.js +4 -0
  11. package/dist/chunks/components-db68vsn7.js +4 -0
  12. package/dist/chunks/content-source-1449qesq.js +4 -0
  13. package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
  14. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  15. package/dist/chunks/editor-x9jn86a7.js +4 -0
  16. package/dist/chunks/entry-commands-may24cpt.js +4 -0
  17. package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
  18. package/dist/chunks/file-ops-x9v54pcj.js +4 -0
  19. package/dist/chunks/files-j3knqf0s.js +4 -0
  20. package/dist/chunks/format-host-tyre2trb.js +4 -0
  21. package/dist/chunks/fs-events-64ma9htc.js +4 -0
  22. package/dist/chunks/git-panel-84ps5dex.js +4 -0
  23. package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
  24. package/dist/chunks/icons-pnfz478q.js +4 -0
  25. package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
  26. package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
  27. package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
  28. package/dist/chunks/iframe-entry-zap785cw.js +5 -0
  29. package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
  30. package/dist/chunks/index-b8xw3vy9.js +4 -0
  31. package/dist/chunks/{index-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
  34. package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
  35. package/dist/chunks/layers-h4xp1pss.js +4 -0
  36. package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
  37. package/dist/chunks/listbox-e74qjyq6.js +4 -0
  38. package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
  39. package/dist/chunks/media-picker-2cweexc5.js +4 -0
  40. package/dist/chunks/menu-n6yzswmy.js +4 -0
  41. package/dist/chunks/menu-ynw13y0s.js +4 -0
  42. package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
  43. package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
  44. package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
  45. package/dist/chunks/notify-cj5zbrs2.js +4 -0
  46. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  47. package/dist/chunks/parse-b7ddhr8m.js +4 -0
  48. package/dist/chunks/platform-3dfws9js.js +4 -0
  49. package/dist/chunks/popover-jt2gxmzs.js +4 -0
  50. package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
  51. package/dist/chunks/quick-search-0dajrwqg.js +4 -0
  52. package/dist/chunks/references-49qgt404.js +4 -0
  53. package/dist/chunks/right-panel-jm1bwe53.js +4 -0
  54. package/dist/chunks/section-registry-6kwc4fky.js +4 -0
  55. package/dist/chunks/select-rzds841e.js +4 -0
  56. package/dist/chunks/split-n2gfpm5m.js +4 -0
  57. package/dist/chunks/{studio-1q1sh2ax.js → studio-0q988f9w.js} +3 -3
  58. package/dist/chunks/studio-0rt52vpq.js +5 -0
  59. package/dist/chunks/studio-18vgbhs5.js +5 -0
  60. package/dist/chunks/{studio-h46vtzk8.js → studio-1fxkaaea.js} +4 -4
  61. package/dist/chunks/studio-24mccdrj.js +5 -0
  62. package/dist/chunks/studio-2eh507zk.js +9 -0
  63. package/dist/chunks/studio-2hcbccfv.js +5 -0
  64. package/dist/chunks/studio-2j1cb95x.js +5 -0
  65. package/dist/chunks/studio-2jbs3rxv.js +5 -0
  66. package/dist/chunks/{studio-rv11kfwa.js → studio-485046te.js} +7 -7
  67. package/dist/chunks/studio-4h8k4dw9.js +5 -0
  68. package/dist/chunks/studio-5f6n18kx.js +5 -0
  69. package/dist/chunks/studio-5gthpky6.js +5 -0
  70. package/dist/chunks/studio-5ve6bbep.js +5 -0
  71. package/dist/chunks/studio-6ep3js6b.js +9 -0
  72. package/dist/chunks/studio-6wkmf3wz.js +9 -0
  73. package/dist/chunks/studio-841rf3cg.js +5 -0
  74. package/dist/chunks/studio-8gmwgheg.js +5 -0
  75. package/dist/chunks/studio-8qm0ep50.js +5 -0
  76. package/dist/chunks/{studio-8grwxtqk.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-pre0skq6.js → studio-a3g98wjr.js} +4 -4
  79. package/dist/chunks/studio-a3shpz9y.js +5 -0
  80. package/dist/chunks/studio-amsbaaar.js +6 -0
  81. package/dist/chunks/studio-at5spjbc.js +7 -0
  82. package/dist/chunks/studio-b2xv945e.js +5 -0
  83. package/dist/chunks/studio-bn5nkafw.js +5 -0
  84. package/dist/chunks/studio-bw6q5xjf.js +9 -0
  85. package/dist/chunks/studio-c7q0t9x1.js +5 -0
  86. package/dist/chunks/studio-camnhc96.js +6 -0
  87. package/dist/chunks/studio-cffqvnzd.js +5 -0
  88. package/dist/chunks/studio-d81xfh1g.js +5 -0
  89. package/dist/chunks/studio-dgz8d0c1.js +5 -0
  90. package/dist/chunks/studio-efvfrsf8.js +5 -0
  91. package/dist/chunks/studio-er30bpcx.js +5 -0
  92. package/dist/chunks/studio-ezscgr64.js +5 -0
  93. package/dist/chunks/studio-ffrrncvz.js +5 -0
  94. package/dist/chunks/studio-fpphgn8y.js +10 -0
  95. package/dist/chunks/studio-j1kvhdjk.js +4 -0
  96. package/dist/chunks/{studio-vrmcjf9g.js → studio-j430n16g.js} +5 -5
  97. package/dist/chunks/studio-jjkg84nj.js +5 -0
  98. package/dist/chunks/studio-m0q32ars.js +4 -0
  99. package/dist/chunks/studio-m6bdst11.js +5 -0
  100. package/dist/chunks/studio-nv2cptd4.js +64 -0
  101. package/dist/chunks/studio-nwfrc98n.js +5 -0
  102. package/dist/chunks/studio-p1wgvp7r.js +5 -0
  103. package/dist/chunks/studio-pag2wncm.js +5 -0
  104. package/dist/chunks/studio-qvanvzfd.js +5 -0
  105. package/dist/chunks/studio-qwa64kt7.js +5 -0
  106. package/dist/chunks/studio-rk1zc4x3.js +928 -0
  107. package/dist/chunks/studio-se2r3ptc.js +5 -0
  108. package/dist/chunks/studio-sg2a0dh0.js +5 -0
  109. package/dist/chunks/studio-tjzjhe68.js +5 -0
  110. package/dist/chunks/{studio-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-kggey1jt.js → studio-v0jzqdjm.js} +4 -4
  112. package/dist/chunks/studio-v2w7q8r1.js +7 -0
  113. package/dist/chunks/studio-v5vjq1h0.js +4 -0
  114. package/dist/chunks/studio-v8aga3vp.js +14 -0
  115. package/dist/chunks/studio-vfcdrfmv.js +5 -0
  116. package/dist/chunks/studio-vmfkgdjf.js +5 -0
  117. package/dist/chunks/studio-wt1816jj.js +5 -0
  118. package/dist/chunks/studio-wz73q5kq.js +4 -0
  119. package/dist/chunks/studio-y04qtxvp.js +7 -0
  120. package/dist/chunks/studio-y21g8zzg.js +5 -0
  121. package/dist/chunks/{studio-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
  122. package/dist/chunks/studio-ynn90f58.js +16 -0
  123. package/dist/chunks/studio-yxz682sx.js +5 -0
  124. package/dist/chunks/studio-zp7snvkq.js +5 -0
  125. package/dist/chunks/studio-zq4z6tm6.js +5 -0
  126. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  127. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  128. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  129. package/dist/chunks/toast-c9fn075p.js +4 -0
  130. package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
  131. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  132. package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
  133. package/dist/chunks/tree-mdq3v5cw.js +4 -0
  134. package/dist/chunks/{tsMode-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
  135. package/dist/chunks/workspace-jtfahpee.js +4 -0
  136. package/dist/chunks/ws-client-nze0k6mv.js +4 -0
  137. package/dist/iframe-entry.js +16 -16
  138. package/dist/manifest.json +63 -63
  139. package/dist/studio.js +97 -97
  140. package/package.json +6 -6
  141. package/src/about/about-modal.ts +4 -3
  142. package/src/account/action-flow.ts +45 -38
  143. package/src/account-status.ts +7 -2
  144. package/src/browse/library-layouts.ts +8 -5
  145. package/src/browse/library-model.ts +18 -6
  146. package/src/browse/library-pane.ts +37 -21
  147. package/src/browse/library-preview.ts +14 -9
  148. package/src/browse/library-source.ts +1 -1
  149. package/src/canvas/asset-refs.ts +24 -9
  150. package/src/canvas/asset-resolve.ts +19 -23
  151. package/src/canvas/canvas-helpers.ts +7 -6
  152. package/src/canvas/canvas-live-render.ts +44 -53
  153. package/src/canvas/canvas-patcher.ts +30 -30
  154. package/src/canvas/canvas-perf.ts +11 -5
  155. package/src/canvas/canvas-render.ts +62 -41
  156. package/src/canvas/canvas-surface.ts +5 -3
  157. package/src/canvas/canvas-utils.ts +90 -49
  158. package/src/canvas/dialog-path.ts +9 -4
  159. package/src/canvas/dialog-state.ts +1 -2
  160. package/src/canvas/diff-marks.ts +9 -16
  161. package/src/canvas/diff-toolbar.ts +8 -7
  162. package/src/canvas/edit-width-drag.ts +4 -1
  163. package/src/canvas/edit-width.ts +1 -3
  164. package/src/canvas/iframe-channel.ts +27 -13
  165. package/src/canvas/iframe-drop.ts +13 -12
  166. package/src/canvas/iframe-editable-root.ts +29 -16
  167. package/src/canvas/iframe-entry.ts +80 -63
  168. package/src/canvas/iframe-eval.ts +73 -49
  169. package/src/canvas/iframe-host.ts +135 -96
  170. package/src/canvas/iframe-inline-edit.ts +49 -30
  171. package/src/canvas/iframe-insert.ts +5 -4
  172. package/src/canvas/iframe-interaction.ts +30 -25
  173. package/src/canvas/iframe-overlay.ts +1 -1
  174. package/src/canvas/iframe-patch.ts +18 -15
  175. package/src/canvas/iframe-position.ts +12 -6
  176. package/src/canvas/iframe-protocol.ts +12 -16
  177. package/src/canvas/iframe-render.ts +36 -34
  178. package/src/canvas/iframe-slash.ts +24 -11
  179. package/src/canvas/iframe-subtree.ts +6 -2
  180. package/src/canvas/path-mapping.ts +19 -12
  181. package/src/canvas/popover-path.ts +7 -3
  182. package/src/canvas/popover-state.ts +1 -2
  183. package/src/canvas/serialize-scope.ts +13 -5
  184. package/src/canvas/stage-scrollbar.ts +2 -1
  185. package/src/canvas/surface-registry.ts +21 -3
  186. package/src/collab/collab-commands.ts +7 -2
  187. package/src/collab/collab-session.ts +84 -45
  188. package/src/collab/collab-state.ts +4 -3
  189. package/src/collab/monaco-binding.ts +16 -13
  190. package/src/collab/monaco-cursors.ts +5 -2
  191. package/src/commands/budget.ts +3 -3
  192. package/src/commands/command-args.ts +103 -71
  193. package/src/commands/context.ts +22 -20
  194. package/src/commands/keymap.ts +47 -43
  195. package/src/commands/levels.ts +3 -3
  196. package/src/commands/live-context.ts +7 -7
  197. package/src/commands/reference.ts +2 -1
  198. package/src/commands/registry.ts +12 -10
  199. package/src/commands/run-reported.ts +15 -10
  200. package/src/component-props.ts +46 -30
  201. package/src/content/collection-match.ts +5 -4
  202. package/src/content/draft-state.ts +4 -3
  203. package/src/content/entry-commands.ts +3 -2
  204. package/src/content/entry-editor.ts +29 -17
  205. package/src/content/entry-fields.ts +12 -7
  206. package/src/content/entry-model.ts +21 -12
  207. package/src/editor/canvas-context-menu.ts +1 -2
  208. package/src/editor/canvas-slash-bridge.ts +3 -6
  209. package/src/editor/content-slice.ts +16 -14
  210. package/src/editor/context-menu.ts +35 -22
  211. package/src/editor/convert-targets.ts +30 -35
  212. package/src/editor/convert-to-component.ts +11 -5
  213. package/src/editor/convert-to-repeater.ts +34 -22
  214. package/src/editor/editable-tags.ts +17 -2
  215. package/src/editor/file-drop-action.ts +21 -22
  216. package/src/editor/inline-edit-apply.ts +35 -17
  217. package/src/editor/inline-edit.ts +66 -50
  218. package/src/editor/inline-format.ts +59 -56
  219. package/src/editor/inline-link.ts +40 -15
  220. package/src/editor/insert-zone-action.ts +1 -1
  221. package/src/editor/merge-tags.ts +58 -19
  222. package/src/editor/repeater-scope.ts +39 -28
  223. package/src/editor/shortcuts.ts +32 -20
  224. package/src/editor/slash-menu.ts +1 -6
  225. package/src/files/asset-versions.ts +4 -4
  226. package/src/files/components.ts +15 -10
  227. package/src/files/elements.ts +5 -6
  228. package/src/files/file-ops.ts +77 -36
  229. package/src/files/files.ts +90 -95
  230. package/src/files/media-meta.ts +2 -1
  231. package/src/files/media-paths.ts +3 -0
  232. package/src/files/serialize-document.ts +2 -2
  233. package/src/format/constraints.ts +1 -1
  234. package/src/format/convert-file.ts +27 -13
  235. package/src/format/format-choices.ts +2 -1
  236. package/src/format/format-host.ts +76 -50
  237. package/src/github/github-auth-status.ts +27 -3
  238. package/src/github/github-auth.ts +19 -9
  239. package/src/github/github-publish.ts +24 -20
  240. package/src/grid/cell-editors.ts +46 -31
  241. package/src/grid/cell-popovers.ts +5 -3
  242. package/src/grid/edit-buffer.ts +10 -9
  243. package/src/grid/grid-controller.ts +20 -22
  244. package/src/grid/grid-layout.ts +21 -5
  245. package/src/grid/grid-open.ts +3 -6
  246. package/src/grid/grid-panel.ts +11 -4
  247. package/src/grid/grid-source.ts +8 -8
  248. package/src/grid/grid-view.ts +14 -17
  249. package/src/grid/redirects-grid.ts +14 -5
  250. package/src/grid/redirects.ts +16 -14
  251. package/src/grid/schema-columns.ts +25 -19
  252. package/src/grid/sources/connector-source.ts +47 -20
  253. package/src/grid/sources/content-source.ts +25 -24
  254. package/src/grid/sources/csv-file-source.ts +2 -2
  255. package/src/grid/tabulator-tables.d.ts +55 -34
  256. package/src/hosting/stage.ts +7 -7
  257. package/src/i18n/i18n-commands.ts +1 -2
  258. package/src/media/media-pane.ts +4 -1
  259. package/src/new-project/add-repo-modal.ts +20 -19
  260. package/src/new-project/import-tab.ts +10 -14
  261. package/src/new-project/location-fields.ts +2 -1
  262. package/src/new-project/new-project-modal.ts +12 -9
  263. package/src/packages/jxsuite-update.ts +4 -3
  264. package/src/packages/pull-package-sync.ts +26 -25
  265. package/src/page-params.ts +97 -68
  266. package/src/panels/activity-panel.ts +17 -9
  267. package/src/panels/ai-chat/attached-context.ts +13 -7
  268. package/src/panels/ai-chat/chat-view.ts +80 -73
  269. package/src/panels/ai-chat/composer.ts +30 -33
  270. package/src/panels/ai-chat/sessions-view.ts +1 -2
  271. package/src/panels/ai-panel.ts +23 -20
  272. package/src/panels/block-action-bar.ts +46 -35
  273. package/src/panels/bottom-dock.ts +5 -3
  274. package/src/panels/canvas-dnd-bridge.ts +31 -24
  275. package/src/panels/data-explorer.ts +62 -25
  276. package/src/panels/data-grid.ts +14 -11
  277. package/src/panels/dnd.ts +108 -118
  278. package/src/panels/editors.ts +52 -21
  279. package/src/panels/elements-panel.ts +10 -3
  280. package/src/panels/events-panel.ts +84 -69
  281. package/src/panels/formula-workspace.ts +76 -51
  282. package/src/panels/frontmatter-fields.ts +24 -19
  283. package/src/panels/frontmatter-panel.ts +44 -34
  284. package/src/panels/git-diff-open.ts +4 -4
  285. package/src/panels/git-panel.ts +49 -61
  286. package/src/panels/head-panel.ts +131 -111
  287. package/src/panels/i18n-panel.ts +10 -3
  288. package/src/panels/imports-panel.ts +23 -47
  289. package/src/panels/jump-bar.ts +48 -29
  290. package/src/panels/layers-panel.ts +97 -74
  291. package/src/panels/left-panel.ts +3 -3
  292. package/src/panels/pane-context.ts +31 -22
  293. package/src/panels/pane-grid.ts +49 -20
  294. package/src/panels/panel-registry.ts +22 -37
  295. package/src/panels/properties-panel.ts +175 -121
  296. package/src/panels/quick-search.ts +53 -31
  297. package/src/panels/right-panel.ts +3 -3
  298. package/src/panels/seo-modal.ts +13 -17
  299. package/src/panels/settings-menu.ts +15 -15
  300. package/src/panels/signals-panel.ts +153 -131
  301. package/src/panels/statement-editor.ts +230 -140
  302. package/src/panels/style-panel.ts +218 -205
  303. package/src/panels/style-utils.ts +114 -51
  304. package/src/panels/stylebook-doc.ts +57 -54
  305. package/src/panels/stylebook-layers-panel.ts +9 -9
  306. package/src/panels/stylebook-panel.ts +13 -17
  307. package/src/panels/tab-drop.ts +27 -11
  308. package/src/panels/tab-strip.ts +36 -26
  309. package/src/platform-errors.ts +57 -43
  310. package/src/platform.ts +58 -30
  311. package/src/platforms/cloud.ts +345 -175
  312. package/src/platforms/default-platform.ts +10 -4
  313. package/src/platforms/devserver.ts +129 -117
  314. package/src/platforms/read-batcher.ts +16 -8
  315. package/src/project-list.ts +2 -1
  316. package/src/publish/deploy-checklist.ts +8 -2
  317. package/src/publish/pages-service.ts +28 -13
  318. package/src/publish/publish-commands.ts +5 -4
  319. package/src/publish/publish-panel.ts +10 -6
  320. package/src/recent-projects.ts +15 -8
  321. package/src/resize-edges.ts +26 -36
  322. package/src/services/a11y-report.ts +26 -19
  323. package/src/services/agent-seed.ts +23 -11
  324. package/src/services/ai-ask.ts +9 -12
  325. package/src/services/ai-command-tools.ts +68 -62
  326. package/src/services/ai-import-tools.ts +80 -67
  327. package/src/services/ai-models.ts +17 -13
  328. package/src/services/ai-project-tools.ts +68 -32
  329. package/src/services/ai-session-store.ts +19 -10
  330. package/src/services/ai-system-prompt.ts +46 -20
  331. package/src/services/ai-tools.ts +71 -27
  332. package/src/services/ai-write-report.ts +20 -12
  333. package/src/services/ai-writes.ts +4 -4
  334. package/src/services/automation.ts +58 -31
  335. package/src/services/cem-export.ts +149 -58
  336. package/src/services/clock.ts +6 -1
  337. package/src/services/code-services.ts +37 -31
  338. package/src/services/context-manager.ts +14 -10
  339. package/src/services/context-resolver.ts +20 -8
  340. package/src/services/data-service.ts +19 -15
  341. package/src/services/directory-picker.ts +18 -12
  342. package/src/services/document-assistant.ts +39 -19
  343. package/src/services/gated-registry.ts +10 -6
  344. package/src/services/harness/chat-reducer.ts +23 -1
  345. package/src/services/import-client.ts +91 -38
  346. package/src/services/import-seed.ts +8 -2
  347. package/src/services/jx-validate.ts +28 -31
  348. package/src/services/live-preview.ts +0 -0
  349. package/src/services/live-surfaces.ts +6 -3
  350. package/src/services/model-uri.ts +10 -2
  351. package/src/services/module-preloads.ts +12 -8
  352. package/src/services/monaco-buffer.ts +43 -24
  353. package/src/services/monaco-lazy.ts +7 -8
  354. package/src/services/monaco-setup.ts +23 -16
  355. package/src/services/notify.ts +44 -17
  356. package/src/services/popover-report.ts +25 -10
  357. package/src/services/preview-eval.ts +20 -8
  358. package/src/services/profile.ts +13 -6
  359. package/src/services/project-path.ts +13 -10
  360. package/src/services/references.ts +0 -0
  361. package/src/services/render-critic.ts +8 -7
  362. package/src/services/settings/kernel.ts +13 -4
  363. package/src/services/settings/write-queue.ts +9 -9
  364. package/src/services/token-lint.ts +12 -10
  365. package/src/services/tool-executor.ts +17 -5
  366. package/src/services/tool-outcomes.ts +44 -24
  367. package/src/services/trusted-types.ts +24 -7
  368. package/src/settings/contexts-section.ts +11 -8
  369. package/src/settings/contributed-section.ts +79 -60
  370. package/src/settings/css-vars-editor.ts +37 -16
  371. package/src/settings/defs-editor.ts +38 -35
  372. package/src/settings/extension-rows.ts +16 -8
  373. package/src/settings/extension-sections.ts +23 -13
  374. package/src/settings/extensions-section.ts +4 -1
  375. package/src/settings/general-settings.ts +11 -8
  376. package/src/settings/locales-section.ts +20 -12
  377. package/src/settings/preferences-dialog.ts +9 -6
  378. package/src/settings/preferences-keymap.ts +7 -5
  379. package/src/settings/preferences-sections.ts +11 -5
  380. package/src/settings/project-sections.ts +1 -1
  381. package/src/settings/schema-field-ui.ts +9 -0
  382. package/src/settings/settings-document.ts +5 -5
  383. package/src/shell/tree.ts +6 -5
  384. package/src/shell.ts +104 -81
  385. package/src/site-context.ts +37 -22
  386. package/src/state.ts +41 -49
  387. package/src/store.ts +54 -34
  388. package/src/studio.ts +25 -75
  389. package/src/style/live-preview.ts +1 -1
  390. package/src/style/project-styles.ts +6 -7
  391. package/src/style/token-ref.ts +5 -4
  392. package/src/surfaces/about.ts +18 -19
  393. package/src/surfaces/add-repo.ts +17 -19
  394. package/src/surfaces/ai-chat.ts +31 -36
  395. package/src/surfaces/ai-credentials-form.ts +6 -16
  396. package/src/surfaces/ai-managed-connect.ts +3 -4
  397. package/src/surfaces/ai-model-picker.ts +3 -5
  398. package/src/surfaces/block-action-bar.ts +22 -11
  399. package/src/surfaces/boot-failure.ts +4 -5
  400. package/src/surfaces/bottom-dock.ts +9 -18
  401. package/src/surfaces/canvas-stage.ts +12 -11
  402. package/src/surfaces/cf-account-picker.ts +17 -18
  403. package/src/surfaces/commandbar.ts +14 -9
  404. package/src/surfaces/convert-repeater.ts +17 -19
  405. package/src/surfaces/data-actions.ts +9 -7
  406. package/src/surfaces/dialog.ts +26 -28
  407. package/src/surfaces/diff-toolbar.ts +9 -7
  408. package/src/surfaces/doc-header.ts +10 -19
  409. package/src/surfaces/empty-state.ts +7 -10
  410. package/src/surfaces/entry-editor.ts +14 -11
  411. package/src/surfaces/expression-editor.ts +11 -25
  412. package/src/surfaces/files-panel.ts +27 -14
  413. package/src/surfaces/formula-palette.ts +4 -5
  414. package/src/surfaces/git-panel.ts +7 -15
  415. package/src/surfaces/github-auth.ts +16 -20
  416. package/src/surfaces/github-publish.ts +17 -22
  417. package/src/surfaces/grid-cell.ts +30 -31
  418. package/src/surfaces/grid-open.ts +10 -14
  419. package/src/surfaces/grid-panel.ts +13 -9
  420. package/src/surfaces/grid-replace.ts +13 -13
  421. package/src/surfaces/grid-views.ts +15 -18
  422. package/src/surfaces/inspector-dock.ts +13 -12
  423. package/src/surfaces/jump-bar.ts +5 -6
  424. package/src/surfaces/jxsuite-update.ts +16 -22
  425. package/src/surfaces/library-pane.ts +19 -20
  426. package/src/surfaces/logic-panel.ts +17 -30
  427. package/src/surfaces/logic-workspace.ts +13 -15
  428. package/src/surfaces/media-browser.ts +11 -10
  429. package/src/surfaces/media-field.ts +4 -5
  430. package/src/surfaces/media-pane.ts +8 -7
  431. package/src/surfaces/menu.ts +29 -23
  432. package/src/surfaces/navigator-dock.ts +11 -12
  433. package/src/surfaces/new-project.ts +27 -26
  434. package/src/surfaces/pane-context.ts +20 -25
  435. package/src/surfaces/pane-grid.ts +15 -10
  436. package/src/surfaces/panel-activity.ts +5 -6
  437. package/src/surfaces/panel-data.ts +3 -4
  438. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  439. package/src/surfaces/panel-elements.ts +5 -7
  440. package/src/surfaces/panel-i18n.ts +5 -7
  441. package/src/surfaces/panel-imports.ts +6 -13
  442. package/src/surfaces/panel-outline.ts +25 -19
  443. package/src/surfaces/panel-page.ts +11 -18
  444. package/src/surfaces/panel-problems.ts +5 -7
  445. package/src/surfaces/panel-signals.ts +20 -34
  446. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  447. package/src/surfaces/preferences.ts +21 -11
  448. package/src/surfaces/progress-modal.ts +15 -9
  449. package/src/surfaces/properties-panel.json +1 -1
  450. package/src/surfaces/properties-panel.ts +20 -42
  451. package/src/surfaces/publish.ts +18 -18
  452. package/src/surfaces/push-plan.ts +7 -8
  453. package/src/surfaces/rail.ts +13 -13
  454. package/src/surfaces/reference-field.ts +11 -15
  455. package/src/surfaces/schema-builder.ts +16 -22
  456. package/src/surfaces/schema-form.ts +15 -25
  457. package/src/surfaces/secret-field.ts +9 -6
  458. package/src/surfaces/seo.ts +21 -15
  459. package/src/surfaces/settings-contexts.ts +9 -7
  460. package/src/surfaces/settings-contributed.ts +14 -10
  461. package/src/surfaces/settings-css-vars.ts +5 -12
  462. package/src/surfaces/settings-defs.json +2 -2
  463. package/src/surfaces/settings-defs.ts +17 -21
  464. package/src/surfaces/settings-deploy.ts +8 -15
  465. package/src/surfaces/settings-extensions.ts +5 -6
  466. package/src/surfaces/settings-head.ts +33 -39
  467. package/src/surfaces/settings-locales.ts +8 -20
  468. package/src/surfaces/settings-overview.ts +5 -6
  469. package/src/surfaces/settings-packages.ts +8 -7
  470. package/src/surfaces/settings-pane.ts +9 -18
  471. package/src/surfaces/settings-rawjson.ts +5 -6
  472. package/src/surfaces/shell.ts +1 -2
  473. package/src/surfaces/slash-menu.ts +19 -9
  474. package/src/surfaces/statements.ts +13 -18
  475. package/src/surfaces/statusbar.ts +17 -14
  476. package/src/surfaces/style-panel.ts +18 -31
  477. package/src/surfaces/stylebook-chrome.ts +3 -5
  478. package/src/surfaces/tab-strip.ts +14 -13
  479. package/src/surfaces/target-line.ts +6 -7
  480. package/src/surfaces/welcome.ts +5 -7
  481. package/src/tabs/patch-ops.ts +4 -3
  482. package/src/tabs/project-config.ts +32 -21
  483. package/src/tabs/selection.ts +36 -8
  484. package/src/tabs/tab.ts +52 -41
  485. package/src/tabs/transact.ts +98 -53
  486. package/src/types.ts +32 -17
  487. package/src/ui/ai-credentials-form.ts +10 -13
  488. package/src/ui/ai-model-picker.ts +3 -3
  489. package/src/ui/cf-account-picker.ts +7 -9
  490. package/src/ui/color-selector.ts +9 -5
  491. package/src/ui/dynamic-slot.ts +7 -8
  492. package/src/ui/expression-editor.ts +112 -105
  493. package/src/ui/form-controls.ts +57 -48
  494. package/src/ui/formula-catalog.ts +239 -230
  495. package/src/ui/formula-chips.ts +33 -18
  496. package/src/ui/layers.ts +44 -31
  497. package/src/ui/media-picker.ts +18 -9
  498. package/src/ui/popover-surface.ts +20 -12
  499. package/src/ui/progress-modal.ts +13 -8
  500. package/src/ui/regions.ts +7 -6
  501. package/src/ui/schema-form.ts +113 -70
  502. package/src/ui/surface.ts +71 -8
  503. package/src/ui/timing.ts +9 -0
  504. package/src/ui/value-source.ts +44 -31
  505. package/src/ui/virtual-window.ts +3 -2
  506. package/src/utils/base64.ts +3 -1
  507. package/src/utils/edit-display.ts +73 -73
  508. package/src/utils/element-selectors.ts +3 -2
  509. package/src/utils/google-fonts.ts +15 -14
  510. package/src/utils/inherited-style.ts +18 -20
  511. package/src/utils/link-target.ts +1 -1
  512. package/src/utils/preview-format.ts +25 -3
  513. package/src/utils/strip-events.ts +49 -22
  514. package/src/utils/studio-utils.ts +29 -14
  515. package/src/view.ts +2 -3
  516. package/src/workspace/pane-derive.ts +10 -12
  517. package/src/workspace/session.ts +53 -43
  518. package/src/workspace/workspace.ts +40 -36
  519. package/dist/chunks/adapter-f93pafd7.js +0 -4
  520. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  521. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  522. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  523. package/dist/chunks/color-field-embq5ctg.js +0 -4
  524. package/dist/chunks/color-fpezvnkt.js +0 -4
  525. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  526. package/dist/chunks/combobox-773hdzyj.js +0 -4
  527. package/dist/chunks/components-ax2f1fnn.js +0 -4
  528. package/dist/chunks/content-source-108aqtk1.js +0 -4
  529. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  530. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  531. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  532. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  533. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  534. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  535. package/dist/chunks/files-44vp8a2s.js +0 -4
  536. package/dist/chunks/format-host-7q1petb9.js +0 -4
  537. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  538. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  539. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  540. package/dist/chunks/icons-p44xhjf0.js +0 -4
  541. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  542. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  543. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  544. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  545. package/dist/chunks/index-wkyfjeqz.js +0 -4
  546. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  547. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  548. package/dist/chunks/layers-xd92fg8d.js +0 -4
  549. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  550. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  551. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  552. package/dist/chunks/menu-37d07z9m.js +0 -4
  553. package/dist/chunks/menu-5c55ea3d.js +0 -4
  554. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  555. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  556. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  557. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  558. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  559. package/dist/chunks/parse-897fvqah.js +0 -4
  560. package/dist/chunks/platform-v1qctbe6.js +0 -4
  561. package/dist/chunks/popover-8htra4er.js +0 -4
  562. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  563. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  564. package/dist/chunks/references-gmqp82fs.js +0 -4
  565. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  566. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  567. package/dist/chunks/select-n3v7gwas.js +0 -4
  568. package/dist/chunks/split-pff8f3ze.js +0 -4
  569. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  570. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  571. package/dist/chunks/studio-1b04pd0j.js +0 -64
  572. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  573. package/dist/chunks/studio-4tanh828.js +0 -5
  574. package/dist/chunks/studio-55h4mstj.js +0 -4
  575. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  576. package/dist/chunks/studio-60dqgb0c.js +0 -5
  577. package/dist/chunks/studio-61dp09qg.js +0 -9
  578. package/dist/chunks/studio-63epcrj2.js +0 -5
  579. package/dist/chunks/studio-74k29dy9.js +0 -5
  580. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  581. package/dist/chunks/studio-7zx31knw.js +0 -9
  582. package/dist/chunks/studio-8bxk97km.js +0 -5
  583. package/dist/chunks/studio-933e30n4.js +0 -5
  584. package/dist/chunks/studio-98wnwhbg.js +0 -5
  585. package/dist/chunks/studio-9mccjwjh.js +0 -14
  586. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  587. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  588. package/dist/chunks/studio-e81q1vb9.js +0 -5
  589. package/dist/chunks/studio-epgrmqqm.js +0 -5
  590. package/dist/chunks/studio-ery42sqr.js +0 -4
  591. package/dist/chunks/studio-g1shz58g.js +0 -5
  592. package/dist/chunks/studio-gf0fz03c.js +0 -5
  593. package/dist/chunks/studio-gjtpe62q.js +0 -6
  594. package/dist/chunks/studio-gkskhg7m.js +0 -5
  595. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  596. package/dist/chunks/studio-j03zga3y.js +0 -9
  597. package/dist/chunks/studio-jhpxeckz.js +0 -5
  598. package/dist/chunks/studio-k01r7ykp.js +0 -5
  599. package/dist/chunks/studio-kk7h30ne.js +0 -7
  600. package/dist/chunks/studio-kt1zqney.js +0 -5
  601. package/dist/chunks/studio-m3cwhvye.js +0 -5
  602. package/dist/chunks/studio-mcayt6hz.js +0 -5
  603. package/dist/chunks/studio-myjcghv3.js +0 -5
  604. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  605. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  606. package/dist/chunks/studio-nj5a01jy.js +0 -928
  607. package/dist/chunks/studio-pcgz8heb.js +0 -5
  608. package/dist/chunks/studio-qcsq0t15.js +0 -5
  609. package/dist/chunks/studio-qkstvve9.js +0 -5
  610. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  611. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  612. package/dist/chunks/studio-s8dmmz66.js +0 -5
  613. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  614. package/dist/chunks/studio-szsjbj0g.js +0 -5
  615. package/dist/chunks/studio-t1xzawhr.js +0 -16
  616. package/dist/chunks/studio-t6b6qe31.js +0 -5
  617. package/dist/chunks/studio-tdcprbqb.js +0 -5
  618. package/dist/chunks/studio-vyc0b4he.js +0 -10
  619. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  620. package/dist/chunks/studio-w3hskzqk.js +0 -5
  621. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  622. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  623. package/dist/chunks/studio-y6n42tgs.js +0 -5
  624. package/dist/chunks/studio-yb560vxr.js +0 -5
  625. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  626. package/dist/chunks/studio-yw05w8f0.js +0 -7
  627. package/dist/chunks/studio-z16sgavc.js +0 -5
  628. package/dist/chunks/studio-zyqn40w4.js +0 -5
  629. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  630. package/dist/chunks/tabs-jwthg40w.js +0 -4
  631. package/dist/chunks/textfield-spy3hc77.js +0 -4
  632. package/dist/chunks/toast-4d35zd64.js +0 -4
  633. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  634. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  635. package/dist/chunks/tree-h19v1jfz.js +0 -4
  636. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  637. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
@@ -9,8 +9,15 @@
9
9
 
10
10
  import { setProjectSchemasForMonaco } from "../services/monaco-lazy";
11
11
  import { getPlatform } from "../platform";
12
- import type { ExtensionCatalogEntry, ExtensionsInfo } from "../types";
13
- import type { JxMutableNode } from "@jxsuite/schema/types";
12
+ import type {
13
+ ExtensionCatalogEntry,
14
+ ExtensionsInfo,
15
+ FormatActionRequest,
16
+ ProjectSchemasResponse,
17
+ StudioPlatform,
18
+ } from "../types";
19
+ import { isString } from "@jxsuite/schema/guards";
20
+ import type { JxDocumentValue, JxMutableNode } from "@jxsuite/schema/types";
14
21
 
15
22
  export interface StudioFormatHints {
16
23
  icon?: string;
@@ -25,6 +32,10 @@ export interface StudioFormatHints {
25
32
  inline?: string[];
26
33
  void?: string[];
27
34
  textOnly?: string[];
35
+ /**
36
+ * Per-parent child rules. The registry arrives over the wire unvalidated, so a rule may be a
37
+ * JSON `null`, which every reader treats as a tag the format leaves undeclared.
38
+ */
28
39
  nesting?: Record<
29
40
  string,
30
41
  {
@@ -32,10 +43,9 @@ export interface StudioFormatHints {
32
43
  inline?: boolean;
33
44
  directive?: boolean;
34
45
  only?: string[];
35
- }
46
+ } | null
36
47
  >;
37
48
  };
38
- [key: string]: unknown;
39
49
  }
40
50
 
41
51
  export interface StudioFormat {
@@ -57,10 +67,11 @@ export function loadFormats(): Promise<StudioFormat[]> {
57
67
  if (!_loaded) {
58
68
  _loaded = (async () => {
59
69
  try {
60
- const platform = getPlatform() as {
61
- listFormats?: () => Promise<StudioFormat[]>;
62
- };
63
- _formats = (await platform.listFormats?.()) ?? [];
70
+ const platform = getPlatform();
71
+ /* SAFETY: every backend's formats route serializes its format registry as the records this
72
+ Module declares (`StudioFormat`); the PAL types the payload `unknown[]` only because this
73
+ Module, not `types.ts`, owns that shape. */
74
+ _formats = ((await platform.listFormats?.()) as StudioFormat[] | undefined) ?? [];
64
75
  } catch {
65
76
  _formats = [];
66
77
  }
@@ -100,9 +111,7 @@ export function loadExtensions(): Promise<ExtensionsInfo[]> {
100
111
  if (!_extensionsLoaded) {
101
112
  _extensionsLoaded = (async () => {
102
113
  try {
103
- const platform = getPlatform() as {
104
- listExtensions?: () => Promise<ExtensionsInfo[]>;
105
- };
114
+ const platform = getPlatform();
106
115
  _extensions = (await platform.listExtensions?.()) ?? [];
107
116
  } catch {
108
117
  _extensions = [];
@@ -144,9 +153,7 @@ export function loadExtensionCatalog(): Promise<ExtensionCatalogEntry[]> {
144
153
  if (!_catalogLoaded) {
145
154
  _catalogLoaded = (async () => {
146
155
  try {
147
- const platform = getPlatform() as {
148
- listExtensionCatalog?: () => Promise<ExtensionCatalogEntry[]>;
149
- };
156
+ const platform = getPlatform();
150
157
  _catalog = (await platform.listExtensionCatalog?.()) ?? [];
151
158
  } catch {
152
159
  _catalog = [];
@@ -180,10 +187,10 @@ export function setExtensionCatalog(catalog: ExtensionCatalogEntry[]) {
180
187
  * @param {object} platform - The studio platform (only `fetchProjectSchemas` is consulted)
181
188
  * @returns {Promise<void>} Resolves once both consumers have been updated
182
189
  */
183
- async function shareProjectSchemas(platform: {
184
- fetchProjectSchemas?: () => Promise<{ project?: unknown; document?: unknown }>;
185
- }): Promise<void> {
186
- let schemas: { project?: unknown; document?: unknown } | null = null;
190
+ async function shareProjectSchemas(
191
+ platform: Pick<StudioPlatform, "fetchProjectSchemas">,
192
+ ): Promise<void> {
193
+ let schemas: ProjectSchemasResponse | null = null;
187
194
  try {
188
195
  schemas = (await platform.fetchProjectSchemas?.()) ?? null;
189
196
  } catch {
@@ -208,9 +215,7 @@ async function shareProjectSchemas(platform: {
208
215
  *
209
216
  * @param {object} platform - The studio platform (only `fetchProjectSchemas` is consulted here)
210
217
  */
211
- export function refreshExtensionUi(platform: {
212
- fetchProjectSchemas?: () => Promise<{ project?: unknown; document?: unknown }>;
213
- }): void {
218
+ export function refreshExtensionUi(platform: Pick<StudioPlatform, "fetchProjectSchemas">): void {
214
219
  void shareProjectSchemas(platform);
215
220
  // `installed` and `bundled` are per-project facts, so an install or a project switch can move
216
221
  // Them even when the shipped half has not changed.
@@ -284,10 +289,20 @@ export function defaultContentFormat(): StudioFormat | undefined {
284
289
  return _formats.find((f) => f.capabilities.serialize && f.documentKinds.includes("content"));
285
290
  }
286
291
 
287
- async function formatAction(payload: Record<string, unknown>): Promise<unknown> {
288
- const platform = getPlatform() as {
289
- formatAction?: (payload: Record<string, unknown>) => Promise<unknown>;
290
- };
292
+ /** The options a format capability is invoked with. */
293
+ export interface FormatActionOptions {
294
+ /** `"roundtrip"` asks the format to preserve what it can of the source's own spelling. */
295
+ mode?: string;
296
+ /** Whether the serializer writes a frontmatter block. */
297
+ frontmatter?: boolean;
298
+ }
299
+
300
+ /**
301
+ * Send one request to the format route (POST /__studio/format, or the desktop RPC of the same
302
+ * name). A serialize request carries the caller's document through unchanged.
303
+ */
304
+ async function formatAction(payload: FormatActionRequest): Promise<JxMutableNode | string> {
305
+ const platform = getPlatform();
291
306
  if (!platform.formatAction) {
292
307
  throw new Error("Platform does not support format actions");
293
308
  }
@@ -298,8 +313,11 @@ async function formatAction(payload: Record<string, unknown>): Promise<unknown>
298
313
  export async function formatParse(
299
314
  name: string,
300
315
  source: string,
301
- options?: Record<string, unknown>,
316
+ options?: FormatActionOptions,
302
317
  ): Promise<JxMutableNode> {
318
+ /* SAFETY: a format class's `parse` capability returns the Jx document it built from the source —
319
+ The contract every format class implements (specs/extensions.md) — and nothing here inspects
320
+ It before `splitFormatDocument` reads its keys. */
303
321
  return (await formatAction({
304
322
  action: "parse",
305
323
  format: name,
@@ -308,12 +326,19 @@ export async function formatParse(
308
326
  })) as JxMutableNode;
309
327
  }
310
328
 
311
- /** Serialize a Jx document to source text via the named format's serialize capability. */
329
+ /**
330
+ * Serialize a Jx document to source text via the named format's serialize capability.
331
+ *
332
+ * `doc` is relayed to the format class verbatim: the document merged with its frontmatter, whose
333
+ * open keys are whatever the format's own parser produced.
334
+ */
312
335
  export async function formatSerialize(
313
336
  name: string,
314
- doc: Record<string, unknown>,
315
- options?: Record<string, unknown>,
337
+ doc: JxMutableNode,
338
+ options?: FormatActionOptions,
316
339
  ): Promise<string> {
340
+ /* SAFETY: a format class's `serialize` capability returns the source text it wrote — the contract
341
+ Every format class implements (specs/extensions.md) — so the answer is a string. */
317
342
  return (await formatAction({
318
343
  action: "serialize",
319
344
  doc,
@@ -322,42 +347,47 @@ export async function formatSerialize(
322
347
  })) as string;
323
348
  }
324
349
 
350
+ /** A document's frontmatter: the open keys of a Jx node, as a format's parser left them. */
351
+ export type FormatFrontmatter = Record<string, JxDocumentValue | undefined>;
352
+
353
+ /** What {@link splitFormatDocument} makes of a parsed format document. */
354
+ export interface SplitFormatDocument {
355
+ document: JxMutableNode;
356
+ frontmatter: FormatFrontmatter;
357
+ mode: "component" | "content";
358
+ }
359
+
325
360
  /**
326
361
  * Split a parsed format document into { document, frontmatter, mode } per the format's
327
362
  * `$studio.documentMode` hints. Component documents (e.g. a frontmatter `tagName` with a hyphen)
328
363
  * keep their full shape; content documents separate frontmatter metadata from the body children.
329
364
  */
330
- export function splitFormatDocument(format: StudioFormat | undefined, doc: JxMutableNode) {
365
+ export function splitFormatDocument(
366
+ format: StudioFormat | undefined,
367
+ doc: JxMutableNode,
368
+ ): SplitFormatDocument {
331
369
  const hints = format?.studio?.documentMode;
332
370
  const componentWhen = hints?.componentWhen;
333
371
  if (componentWhen?.frontmatterKey) {
334
372
  const value = doc[componentWhen.frontmatterKey];
335
373
  const pattern = componentWhen.matches ? new RegExp(componentWhen.matches) : /./;
336
- if (typeof value === "string" && pattern.test(value)) {
337
- return {
338
- document: doc,
339
- frontmatter: {} as Record<string, unknown>,
340
- mode: "component",
341
- };
374
+ if (isString(value) && pattern.test(value)) {
375
+ return { document: doc, frontmatter: {}, mode: "component" };
342
376
  }
343
377
  }
344
378
  if (hints?.default === "component") {
345
- return {
346
- document: doc,
347
- frontmatter: {} as Record<string, unknown>,
348
- mode: "component",
349
- };
379
+ return { document: doc, frontmatter: {}, mode: "component" };
350
380
  }
351
381
 
352
382
  // Content document — children form the root-level body; other keys are frontmatter
353
- const children = (doc.children as unknown[]) ?? [];
354
- if (children.length === 0) {
383
+ const children = doc.children ?? [];
384
+ if (Array.isArray(children) && children.length === 0) {
355
385
  children.push({ children: [], tagName: "p" });
356
386
  }
357
387
 
358
388
  const documentKeys = new Set(["state", "imports"]);
359
- const contentDoc: Record<string, unknown> = { children };
360
- const frontmatter: Record<string, unknown> = {};
389
+ const contentDoc: JxMutableNode = { children };
390
+ const frontmatter: FormatFrontmatter = {};
361
391
  for (const [key, value] of Object.entries(doc)) {
362
392
  if (key === "children") {
363
393
  continue;
@@ -369,9 +399,5 @@ export function splitFormatDocument(format: StudioFormat | undefined, doc: JxMut
369
399
  }
370
400
  }
371
401
 
372
- return {
373
- document: contentDoc as JxMutableNode,
374
- frontmatter,
375
- mode: "content",
376
- };
402
+ return { document: contentDoc, frontmatter, mode: "content" };
377
403
  }
@@ -18,6 +18,14 @@
18
18
 
19
19
  const STORAGE_KEY = "jx_github_token";
20
20
 
21
+ /**
22
+ * The GitHub OAuth app every Jx sign-in authorizes against: the browser's device flow in
23
+ * `github-auth.ts`, and the desktop launcher's RFC 8252 loopback redirect
24
+ * (`packages/desktop/src/github-signin.ts`). Here, in the module with no UI dependency, because the
25
+ * launcher's main process imports it too.
26
+ */
27
+ export const GITHUB_OAUTH_CLIENT_ID = "Ov23liYVlMFpgjOEPXJH";
28
+
21
29
  /**
22
30
  * The desktop launcher's RFC 8252 sign-in, when this build is running inside one.
23
31
  *
@@ -30,13 +38,29 @@ export interface NativeGithubAuth {
30
38
  status: () => Promise<{ stored: boolean }>;
31
39
  }
32
40
 
33
- export function nativeAuth(): NativeGithubAuth | null {
41
+ /**
42
+ * Whether the registered platform object carries a launcher's `githubAuth` member.
43
+ *
44
+ * Presence is the whole test, as it always was: the member is written only by a launcher's adapter
45
+ * (`packages/desktop/src/platform.ts`), which installs a {@link NativeGithubAuth}, and a browser
46
+ * build has no member at all.
47
+ */
48
+ function carriesNativeAuth(platform: unknown): platform is { githubAuth: NativeGithubAuth } {
34
49
  return (
35
- (globalThis as unknown as { __jxPlatform?: { githubAuth?: NativeGithubAuth } }).__jxPlatform
36
- ?.githubAuth ?? null
50
+ typeof platform === "object" &&
51
+ platform !== null &&
52
+ "githubAuth" in platform &&
53
+ platform.githubAuth != null
37
54
  );
38
55
  }
39
56
 
57
+ export function nativeAuth(): NativeGithubAuth | null {
58
+ // `globalThis` as a plain object: its declared type knows nothing of the launcher's slot.
59
+ const host: object = globalThis;
60
+ const platform = "__jxPlatform" in host ? host.__jxPlatform : undefined;
61
+ return carriesNativeAuth(platform) ? platform.githubAuth : null;
62
+ }
63
+
40
64
  /**
41
65
  * The token the desktop store handed us this session.
42
66
  *
@@ -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();
@@ -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)),