@jxsuite/studio 6.1.0 → 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 (645) hide show
  1. package/dist/chunks/2020-f2gkpy8d.js +4 -0
  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-gybvv7a6.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-rnvdp3k4.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/jsonMode-w15cmrcm.js +13 -0
  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-5g0ag7c0.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-pxg4ap1e.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-qbj760tx.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-anyrgzvb.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-v2bvmbjj.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-txjjzrsm.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-0x3jyb8r.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-cpxkgjrj.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-y64hrt8p.js +12 -0
  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-sf49ee9x.js +14 -0
  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 +98 -98
  140. package/dist/workers/ts.worker.js +3 -3
  141. package/package.json +11 -11
  142. package/src/about/about-modal.ts +4 -3
  143. package/src/account/action-flow.ts +45 -38
  144. package/src/account-status.ts +7 -2
  145. package/src/browse/library-layouts.ts +8 -5
  146. package/src/browse/library-model.ts +18 -6
  147. package/src/browse/library-pane.ts +37 -21
  148. package/src/browse/library-preview.ts +14 -9
  149. package/src/browse/library-source.ts +1 -1
  150. package/src/canvas/asset-refs.ts +24 -9
  151. package/src/canvas/asset-resolve.ts +19 -23
  152. package/src/canvas/canvas-helpers.ts +7 -6
  153. package/src/canvas/canvas-live-render.ts +44 -53
  154. package/src/canvas/canvas-patcher.ts +30 -30
  155. package/src/canvas/canvas-perf.ts +11 -5
  156. package/src/canvas/canvas-render.ts +66 -42
  157. package/src/canvas/canvas-surface.ts +5 -3
  158. package/src/canvas/canvas-utils.ts +163 -64
  159. package/src/canvas/dialog-path.ts +9 -4
  160. package/src/canvas/dialog-state.ts +1 -2
  161. package/src/canvas/diff-marks.ts +9 -16
  162. package/src/canvas/diff-toolbar.ts +8 -7
  163. package/src/canvas/edit-width-drag.ts +4 -1
  164. package/src/canvas/edit-width.ts +1 -3
  165. package/src/canvas/iframe-channel.ts +27 -13
  166. package/src/canvas/iframe-drop.ts +13 -12
  167. package/src/canvas/iframe-editable-root.ts +29 -16
  168. package/src/canvas/iframe-entry.ts +80 -63
  169. package/src/canvas/iframe-eval.ts +73 -49
  170. package/src/canvas/iframe-host.ts +203 -118
  171. package/src/canvas/iframe-inline-edit.ts +69 -32
  172. package/src/canvas/iframe-insert.ts +5 -4
  173. package/src/canvas/iframe-interaction.ts +37 -26
  174. package/src/canvas/iframe-overlay.ts +1 -1
  175. package/src/canvas/iframe-patch.ts +18 -15
  176. package/src/canvas/iframe-position.ts +12 -6
  177. package/src/canvas/iframe-protocol.ts +15 -16
  178. package/src/canvas/iframe-render.ts +41 -36
  179. package/src/canvas/iframe-slash.ts +24 -11
  180. package/src/canvas/iframe-subtree.ts +6 -2
  181. package/src/canvas/path-mapping.ts +19 -12
  182. package/src/canvas/popover-path.ts +7 -3
  183. package/src/canvas/popover-state.ts +1 -2
  184. package/src/canvas/serialize-scope.ts +13 -5
  185. package/src/canvas/stage-scrollbar.ts +2 -1
  186. package/src/canvas/surface-registry.ts +21 -3
  187. package/src/collab/collab-commands.ts +7 -2
  188. package/src/collab/collab-session.ts +84 -45
  189. package/src/collab/collab-state.ts +4 -3
  190. package/src/collab/monaco-binding.ts +16 -13
  191. package/src/collab/monaco-cursors.ts +5 -2
  192. package/src/commands/budget.ts +3 -3
  193. package/src/commands/command-args.ts +103 -71
  194. package/src/commands/context.ts +22 -20
  195. package/src/commands/defaults.ts +4 -1
  196. package/src/commands/keymap.ts +47 -43
  197. package/src/commands/levels.ts +3 -3
  198. package/src/commands/live-context.ts +10 -8
  199. package/src/commands/reference.ts +2 -1
  200. package/src/commands/registry.ts +12 -10
  201. package/src/commands/run-reported.ts +15 -10
  202. package/src/component-props.ts +46 -30
  203. package/src/content/collection-match.ts +5 -4
  204. package/src/content/draft-state.ts +4 -3
  205. package/src/content/entry-commands.ts +3 -2
  206. package/src/content/entry-editor.ts +29 -17
  207. package/src/content/entry-fields.ts +12 -7
  208. package/src/content/entry-model.ts +21 -12
  209. package/src/editor/canvas-context-menu.ts +1 -2
  210. package/src/editor/canvas-slash-bridge.ts +3 -6
  211. package/src/editor/content-slice.ts +16 -14
  212. package/src/editor/context-menu.ts +35 -22
  213. package/src/editor/convert-targets.ts +30 -35
  214. package/src/editor/convert-to-component.ts +11 -5
  215. package/src/editor/convert-to-repeater.ts +34 -22
  216. package/src/editor/editable-tags.ts +17 -2
  217. package/src/editor/file-drop-action.ts +21 -22
  218. package/src/editor/inline-edit-apply.ts +35 -17
  219. package/src/editor/inline-edit.ts +66 -50
  220. package/src/editor/inline-format.ts +59 -56
  221. package/src/editor/inline-link.ts +40 -15
  222. package/src/editor/insert-zone-action.ts +1 -1
  223. package/src/editor/merge-tags.ts +58 -19
  224. package/src/editor/repeater-scope.ts +39 -28
  225. package/src/editor/shortcuts.ts +87 -47
  226. package/src/editor/slash-menu.ts +1 -6
  227. package/src/files/asset-versions.ts +4 -4
  228. package/src/files/components.ts +15 -10
  229. package/src/files/elements.ts +5 -6
  230. package/src/files/file-ops.ts +77 -36
  231. package/src/files/files.ts +90 -95
  232. package/src/files/media-meta.ts +2 -1
  233. package/src/files/media-paths.ts +6 -1
  234. package/src/files/serialize-document.ts +2 -2
  235. package/src/format/constraints.ts +1 -1
  236. package/src/format/convert-file.ts +27 -13
  237. package/src/format/format-choices.ts +2 -1
  238. package/src/format/format-host.ts +76 -50
  239. package/src/github/github-auth-status.ts +27 -3
  240. package/src/github/github-auth.ts +19 -9
  241. package/src/github/github-publish.ts +24 -20
  242. package/src/grid/cell-editors.ts +46 -31
  243. package/src/grid/cell-popovers.ts +5 -3
  244. package/src/grid/edit-buffer.ts +10 -9
  245. package/src/grid/grid-controller.ts +20 -22
  246. package/src/grid/grid-layout.ts +21 -5
  247. package/src/grid/grid-open.ts +3 -6
  248. package/src/grid/grid-panel.ts +11 -4
  249. package/src/grid/grid-source.ts +8 -8
  250. package/src/grid/grid-view.ts +14 -17
  251. package/src/grid/redirects-grid.ts +14 -5
  252. package/src/grid/redirects.ts +16 -14
  253. package/src/grid/schema-columns.ts +25 -19
  254. package/src/grid/sources/connector-source.ts +47 -20
  255. package/src/grid/sources/content-source.ts +25 -24
  256. package/src/grid/sources/csv-file-source.ts +2 -2
  257. package/src/grid/tabulator-tables.d.ts +55 -34
  258. package/src/hosting/stage.ts +7 -7
  259. package/src/i18n/i18n-commands.ts +1 -2
  260. package/src/media/media-pane.ts +4 -1
  261. package/src/new-project/add-repo-modal.ts +20 -19
  262. package/src/new-project/import-tab.ts +10 -14
  263. package/src/new-project/location-fields.ts +2 -1
  264. package/src/new-project/new-project-modal.ts +12 -9
  265. package/src/packages/jxsuite-update.ts +4 -3
  266. package/src/packages/pull-package-sync.ts +26 -25
  267. package/src/page-params.ts +97 -68
  268. package/src/panels/activity-panel.ts +17 -9
  269. package/src/panels/ai-chat/attached-context.ts +13 -7
  270. package/src/panels/ai-chat/chat-view.ts +80 -73
  271. package/src/panels/ai-chat/composer.ts +30 -33
  272. package/src/panels/ai-chat/sessions-view.ts +1 -2
  273. package/src/panels/ai-panel.ts +23 -20
  274. package/src/panels/block-action-bar.ts +46 -35
  275. package/src/panels/bottom-dock.ts +5 -3
  276. package/src/panels/canvas-dnd-bridge.ts +31 -24
  277. package/src/panels/data-explorer.ts +62 -25
  278. package/src/panels/data-grid.ts +14 -11
  279. package/src/panels/dnd.ts +108 -118
  280. package/src/panels/editors.ts +55 -22
  281. package/src/panels/elements-panel.ts +10 -3
  282. package/src/panels/events-panel.ts +84 -69
  283. package/src/panels/formula-workspace.ts +76 -51
  284. package/src/panels/frontmatter-fields.ts +24 -19
  285. package/src/panels/frontmatter-panel.ts +44 -34
  286. package/src/panels/git-diff-open.ts +4 -4
  287. package/src/panels/git-panel.ts +49 -61
  288. package/src/panels/head-panel.ts +131 -111
  289. package/src/panels/i18n-panel.ts +10 -3
  290. package/src/panels/imports-panel.ts +23 -47
  291. package/src/panels/jump-bar.ts +48 -29
  292. package/src/panels/layers-panel.ts +97 -74
  293. package/src/panels/left-panel.ts +3 -3
  294. package/src/panels/pane-context.ts +31 -22
  295. package/src/panels/pane-grid.ts +49 -20
  296. package/src/panels/panel-registry.ts +22 -37
  297. package/src/panels/properties-panel.ts +175 -121
  298. package/src/panels/quick-search.ts +53 -31
  299. package/src/panels/right-panel.ts +3 -3
  300. package/src/panels/seo-modal.ts +13 -17
  301. package/src/panels/settings-menu.ts +15 -15
  302. package/src/panels/signals-panel.ts +153 -131
  303. package/src/panels/statement-editor.ts +230 -140
  304. package/src/panels/style-panel.ts +254 -216
  305. package/src/panels/style-utils.ts +114 -51
  306. package/src/panels/stylebook-doc.ts +57 -54
  307. package/src/panels/stylebook-layers-panel.ts +9 -9
  308. package/src/panels/stylebook-panel.ts +13 -17
  309. package/src/panels/tab-drop.ts +27 -11
  310. package/src/panels/tab-strip.ts +36 -26
  311. package/src/platform-errors.ts +57 -43
  312. package/src/platform.ts +58 -30
  313. package/src/platforms/cloud.ts +345 -175
  314. package/src/platforms/default-platform.ts +10 -4
  315. package/src/platforms/devserver.ts +174 -127
  316. package/src/platforms/read-batcher.ts +16 -8
  317. package/src/project-list.ts +2 -1
  318. package/src/publish/deploy-checklist.ts +8 -2
  319. package/src/publish/pages-service.ts +28 -13
  320. package/src/publish/publish-commands.ts +5 -4
  321. package/src/publish/publish-panel.ts +10 -6
  322. package/src/recent-projects.ts +15 -8
  323. package/src/resize-edges.ts +26 -36
  324. package/src/services/a11y-report.ts +26 -19
  325. package/src/services/agent-seed.ts +23 -11
  326. package/src/services/ai-ask.ts +9 -12
  327. package/src/services/ai-command-tools.ts +68 -62
  328. package/src/services/ai-import-tools.ts +80 -67
  329. package/src/services/ai-models.ts +17 -13
  330. package/src/services/ai-project-tools.ts +68 -32
  331. package/src/services/ai-session-store.ts +19 -10
  332. package/src/services/ai-system-prompt.ts +46 -20
  333. package/src/services/ai-tools.ts +71 -27
  334. package/src/services/ai-write-report.ts +20 -12
  335. package/src/services/ai-writes.ts +4 -4
  336. package/src/services/automation.ts +58 -31
  337. package/src/services/cem-export.ts +149 -58
  338. package/src/services/clock.ts +6 -1
  339. package/src/services/code-services.ts +37 -31
  340. package/src/services/context-manager.ts +14 -10
  341. package/src/services/context-resolver.ts +20 -8
  342. package/src/services/data-service.ts +19 -15
  343. package/src/services/directory-picker.ts +18 -12
  344. package/src/services/document-assistant.ts +39 -19
  345. package/src/services/gated-registry.ts +10 -6
  346. package/src/services/harness/chat-reducer.ts +23 -1
  347. package/src/services/import-client.ts +91 -38
  348. package/src/services/import-seed.ts +8 -2
  349. package/src/services/jx-validate.ts +28 -31
  350. package/src/services/live-preview.ts +0 -0
  351. package/src/services/live-surfaces.ts +6 -3
  352. package/src/services/model-uri.ts +10 -2
  353. package/src/services/module-preloads.ts +12 -8
  354. package/src/services/monaco-buffer.ts +43 -24
  355. package/src/services/monaco-lazy.ts +7 -8
  356. package/src/services/monaco-setup.ts +23 -16
  357. package/src/services/notify.ts +44 -17
  358. package/src/services/popover-report.ts +25 -10
  359. package/src/services/preview-eval.ts +20 -8
  360. package/src/services/profile.ts +13 -6
  361. package/src/services/project-path.ts +13 -10
  362. package/src/services/references.ts +0 -0
  363. package/src/services/render-critic.ts +8 -7
  364. package/src/services/settings/kernel.ts +13 -4
  365. package/src/services/settings/write-queue.ts +9 -9
  366. package/src/services/token-lint.ts +12 -10
  367. package/src/services/tool-executor.ts +17 -5
  368. package/src/services/tool-outcomes.ts +44 -24
  369. package/src/services/trusted-types.ts +24 -7
  370. package/src/settings/contexts-section.ts +11 -8
  371. package/src/settings/contributed-section.ts +79 -60
  372. package/src/settings/css-vars-editor.ts +37 -16
  373. package/src/settings/defs-editor.ts +38 -35
  374. package/src/settings/extension-rows.ts +16 -8
  375. package/src/settings/extension-sections.ts +23 -13
  376. package/src/settings/extensions-section.ts +4 -1
  377. package/src/settings/general-settings.ts +11 -8
  378. package/src/settings/locales-section.ts +20 -12
  379. package/src/settings/preferences-dialog.ts +9 -6
  380. package/src/settings/preferences-keymap.ts +7 -5
  381. package/src/settings/preferences-sections.ts +11 -5
  382. package/src/settings/project-sections.ts +1 -1
  383. package/src/settings/schema-field-ui.ts +9 -0
  384. package/src/settings/settings-document.ts +5 -5
  385. package/src/shell/tree.ts +6 -5
  386. package/src/shell.ts +104 -81
  387. package/src/site-context.ts +37 -22
  388. package/src/state.ts +41 -49
  389. package/src/store.ts +54 -34
  390. package/src/studio.ts +39 -77
  391. package/src/style/live-preview.ts +1 -1
  392. package/src/style/project-styles.ts +6 -7
  393. package/src/style/token-ref.ts +5 -4
  394. package/src/surfaces/about.ts +18 -19
  395. package/src/surfaces/add-repo.ts +17 -19
  396. package/src/surfaces/ai-chat.ts +31 -36
  397. package/src/surfaces/ai-credentials-form.ts +6 -16
  398. package/src/surfaces/ai-managed-connect.ts +3 -4
  399. package/src/surfaces/ai-model-picker.ts +3 -5
  400. package/src/surfaces/block-action-bar.ts +22 -11
  401. package/src/surfaces/boot-failure.ts +4 -5
  402. package/src/surfaces/bottom-dock.ts +9 -18
  403. package/src/surfaces/canvas-stage.ts +12 -11
  404. package/src/surfaces/cf-account-picker.ts +17 -18
  405. package/src/surfaces/commandbar.ts +14 -9
  406. package/src/surfaces/convert-repeater.ts +17 -19
  407. package/src/surfaces/data-actions.ts +9 -7
  408. package/src/surfaces/dialog.ts +26 -28
  409. package/src/surfaces/diff-toolbar.ts +9 -7
  410. package/src/surfaces/doc-header.ts +10 -19
  411. package/src/surfaces/empty-state.ts +7 -10
  412. package/src/surfaces/entry-editor.ts +14 -11
  413. package/src/surfaces/expression-editor.ts +11 -25
  414. package/src/surfaces/files-panel.ts +27 -14
  415. package/src/surfaces/formula-palette.ts +4 -5
  416. package/src/surfaces/git-panel.ts +7 -15
  417. package/src/surfaces/github-auth.ts +16 -20
  418. package/src/surfaces/github-publish.ts +17 -22
  419. package/src/surfaces/grid-cell.ts +30 -31
  420. package/src/surfaces/grid-open.ts +10 -14
  421. package/src/surfaces/grid-panel.ts +13 -9
  422. package/src/surfaces/grid-replace.ts +13 -13
  423. package/src/surfaces/grid-views.ts +15 -18
  424. package/src/surfaces/inspector-dock.ts +13 -12
  425. package/src/surfaces/jump-bar.ts +5 -6
  426. package/src/surfaces/jxsuite-update.ts +16 -22
  427. package/src/surfaces/library-pane.ts +25 -20
  428. package/src/surfaces/logic-panel.ts +17 -30
  429. package/src/surfaces/logic-workspace.ts +13 -15
  430. package/src/surfaces/media-browser.ts +11 -10
  431. package/src/surfaces/media-field.ts +4 -5
  432. package/src/surfaces/media-pane.ts +8 -7
  433. package/src/surfaces/menu.ts +29 -23
  434. package/src/surfaces/navigator-dock.ts +11 -12
  435. package/src/surfaces/new-project.ts +27 -26
  436. package/src/surfaces/pane-context.ts +20 -25
  437. package/src/surfaces/pane-grid.ts +15 -10
  438. package/src/surfaces/panel-activity.ts +5 -6
  439. package/src/surfaces/panel-data.ts +3 -4
  440. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  441. package/src/surfaces/panel-elements.ts +5 -7
  442. package/src/surfaces/panel-i18n.ts +5 -7
  443. package/src/surfaces/panel-imports.ts +6 -13
  444. package/src/surfaces/panel-outline.ts +25 -19
  445. package/src/surfaces/panel-page.ts +11 -18
  446. package/src/surfaces/panel-problems.ts +5 -7
  447. package/src/surfaces/panel-signals.ts +20 -34
  448. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  449. package/src/surfaces/preferences.ts +21 -11
  450. package/src/surfaces/progress-modal.ts +15 -9
  451. package/src/surfaces/properties-panel.json +1 -1
  452. package/src/surfaces/properties-panel.ts +20 -42
  453. package/src/surfaces/publish.ts +18 -18
  454. package/src/surfaces/push-plan.ts +7 -8
  455. package/src/surfaces/rail.json +126 -73
  456. package/src/surfaces/rail.ts +38 -12
  457. package/src/surfaces/reference-field.ts +11 -15
  458. package/src/surfaces/schema-builder.ts +16 -22
  459. package/src/surfaces/schema-form.ts +15 -25
  460. package/src/surfaces/secret-field.ts +9 -6
  461. package/src/surfaces/seo.ts +21 -15
  462. package/src/surfaces/settings-contexts.ts +9 -7
  463. package/src/surfaces/settings-contributed.ts +14 -10
  464. package/src/surfaces/settings-css-vars.ts +5 -12
  465. package/src/surfaces/settings-defs.json +2 -2
  466. package/src/surfaces/settings-defs.ts +17 -21
  467. package/src/surfaces/settings-deploy.ts +8 -15
  468. package/src/surfaces/settings-extensions.ts +5 -6
  469. package/src/surfaces/settings-head.ts +33 -39
  470. package/src/surfaces/settings-locales.ts +8 -20
  471. package/src/surfaces/settings-overview.ts +5 -6
  472. package/src/surfaces/settings-packages.ts +8 -7
  473. package/src/surfaces/settings-pane.ts +9 -18
  474. package/src/surfaces/settings-rawjson.ts +5 -6
  475. package/src/surfaces/shell.ts +1 -2
  476. package/src/surfaces/slash-menu.ts +19 -9
  477. package/src/surfaces/statements.ts +13 -18
  478. package/src/surfaces/statusbar.ts +17 -14
  479. package/src/surfaces/style-panel.ts +18 -31
  480. package/src/surfaces/stylebook-chrome.ts +3 -5
  481. package/src/surfaces/tab-strip.ts +14 -13
  482. package/src/surfaces/target-line.ts +6 -7
  483. package/src/surfaces/welcome.ts +5 -7
  484. package/src/tabs/patch-ops.ts +4 -3
  485. package/src/tabs/project-config.ts +32 -21
  486. package/src/tabs/selection.ts +36 -8
  487. package/src/tabs/tab.ts +52 -41
  488. package/src/tabs/transact.ts +98 -53
  489. package/src/tabs/typing.ts +31 -0
  490. package/src/types.ts +32 -17
  491. package/src/ui/ai-credentials-form.ts +10 -13
  492. package/src/ui/ai-model-picker.ts +3 -3
  493. package/src/ui/cf-account-picker.ts +7 -9
  494. package/src/ui/color-selector.ts +9 -5
  495. package/src/ui/dynamic-slot.ts +7 -8
  496. package/src/ui/expression-editor.ts +112 -105
  497. package/src/ui/form-controls.ts +57 -48
  498. package/src/ui/formula-catalog.ts +239 -230
  499. package/src/ui/formula-chips.ts +33 -18
  500. package/src/ui/layers.ts +44 -31
  501. package/src/ui/media-picker.ts +18 -9
  502. package/src/ui/popover-surface.ts +20 -12
  503. package/src/ui/progress-modal.ts +13 -8
  504. package/src/ui/regions.ts +7 -6
  505. package/src/ui/schema-form.ts +113 -70
  506. package/src/ui/surface.ts +71 -8
  507. package/src/ui/timing.ts +9 -0
  508. package/src/ui/value-source.ts +44 -31
  509. package/src/ui/virtual-window.ts +3 -2
  510. package/src/utils/base64.ts +3 -1
  511. package/src/utils/edit-display.ts +103 -74
  512. package/src/utils/element-selectors.ts +3 -2
  513. package/src/utils/google-fonts.ts +15 -14
  514. package/src/utils/inherited-style.ts +18 -20
  515. package/src/utils/link-target.ts +1 -1
  516. package/src/utils/preview-format.ts +25 -3
  517. package/src/utils/strip-events.ts +49 -22
  518. package/src/utils/studio-utils.ts +29 -14
  519. package/src/view.ts +2 -3
  520. package/src/workspace/pane-derive.ts +10 -12
  521. package/src/workspace/session.ts +53 -43
  522. package/src/workspace/workspace.ts +47 -36
  523. package/dist/chunks/2020-nkxms0ay.js +0 -4
  524. package/dist/chunks/adapter-m948ab5f.js +0 -4
  525. package/dist/chunks/cf-account-picker-n8hr38v7.js +0 -4
  526. package/dist/chunks/cf-settings-356xdtne.js +0 -4
  527. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  528. package/dist/chunks/color-field-embq5ctg.js +0 -4
  529. package/dist/chunks/color-fpezvnkt.js +0 -4
  530. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  531. package/dist/chunks/combobox-773hdzyj.js +0 -4
  532. package/dist/chunks/components-yk3t844e.js +0 -4
  533. package/dist/chunks/content-source-bawmyc09.js +0 -4
  534. package/dist/chunks/convert-to-repeater-7wns8kf1.js +0 -4
  535. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  536. package/dist/chunks/editor-6sc8nacq.js +0 -4
  537. package/dist/chunks/entry-commands-8ay9fh81.js +0 -4
  538. package/dist/chunks/extension-sections-na7rj3nr.js +0 -4
  539. package/dist/chunks/file-ops-gye0qw56.js +0 -4
  540. package/dist/chunks/files-dmc2xvcq.js +0 -4
  541. package/dist/chunks/format-host-t76b53f8.js +0 -4
  542. package/dist/chunks/fs-events-cg4tpz06.js +0 -4
  543. package/dist/chunks/git-panel-yef7bshy.js +0 -4
  544. package/dist/chunks/grid-view-7tt4bxw1.js +0 -51
  545. package/dist/chunks/icons-qbh8akb1.js +0 -4
  546. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  547. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  548. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  549. package/dist/chunks/iframe-host-tmz30gfp.js +0 -4
  550. package/dist/chunks/index-nag78a9h.js +0 -4
  551. package/dist/chunks/jsonMode-zhwsprqk.js +0 -13
  552. package/dist/chunks/jx-validate-3gbp5nkn.js +0 -4
  553. package/dist/chunks/layers-fvz99859.js +0 -4
  554. package/dist/chunks/layers-panel-gchmbf9p.js +0 -4
  555. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  556. package/dist/chunks/lit-html-9agdspkt.js +0 -4
  557. package/dist/chunks/media-picker-rhjvyy00.js +0 -4
  558. package/dist/chunks/menu-2e4y9j7b.js +0 -4
  559. package/dist/chunks/menu-37d07z9m.js +0 -4
  560. package/dist/chunks/monaco-binding-2jnhjjvr.js +0 -4
  561. package/dist/chunks/monaco-buffer-rp21359g.js +0 -4
  562. package/dist/chunks/monaco-setup-vhh7gayr.js +0 -4
  563. package/dist/chunks/notify-h3www560.js +0 -4
  564. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  565. package/dist/chunks/parse-897fvqah.js +0 -4
  566. package/dist/chunks/platform-hz34wcd7.js +0 -4
  567. package/dist/chunks/popover-8htra4er.js +0 -4
  568. package/dist/chunks/publish-panel-exsmjzyj.js +0 -4
  569. package/dist/chunks/quick-search-pgaqeh0m.js +0 -4
  570. package/dist/chunks/references-2cgdxnb8.js +0 -4
  571. package/dist/chunks/right-panel-jf856w5w.js +0 -4
  572. package/dist/chunks/section-registry-jnf8r5gy.js +0 -4
  573. package/dist/chunks/select-n3v7gwas.js +0 -4
  574. package/dist/chunks/split-pff8f3ze.js +0 -4
  575. package/dist/chunks/studio-0f55h9ye.js +0 -5
  576. package/dist/chunks/studio-0sqdhnew.js +0 -12
  577. package/dist/chunks/studio-19x1c75w.js +0 -5
  578. package/dist/chunks/studio-2sqcndak.js +0 -5
  579. package/dist/chunks/studio-3aey7dd3.js +0 -5
  580. package/dist/chunks/studio-3bpdkq2s.js +0 -5
  581. package/dist/chunks/studio-47y6fbpf.js +0 -5
  582. package/dist/chunks/studio-4m3826v2.js +0 -5
  583. package/dist/chunks/studio-4nx2dj1g.js +0 -4
  584. package/dist/chunks/studio-4xv5s47r.js +0 -9
  585. package/dist/chunks/studio-5g4t8v6w.js +0 -5
  586. package/dist/chunks/studio-5py436sf.js +0 -5
  587. package/dist/chunks/studio-77kt594t.js +0 -5
  588. package/dist/chunks/studio-8f87n763.js +0 -10
  589. package/dist/chunks/studio-8mb00b84.js +0 -5
  590. package/dist/chunks/studio-8p51gq2h.js +0 -6
  591. package/dist/chunks/studio-954ds834.js +0 -5
  592. package/dist/chunks/studio-9ft45c83.js +0 -9
  593. package/dist/chunks/studio-a2138x5k.js +0 -7
  594. package/dist/chunks/studio-a9yzstqj.js +0 -5
  595. package/dist/chunks/studio-acdksxx6.js +0 -5
  596. package/dist/chunks/studio-ar8jcf2y.js +0 -5
  597. package/dist/chunks/studio-bmn4mn9j.js +0 -7
  598. package/dist/chunks/studio-e7xxa0sj.js +0 -5
  599. package/dist/chunks/studio-ecaz25vk.js +0 -5
  600. package/dist/chunks/studio-ery42sqr.js +0 -4
  601. package/dist/chunks/studio-fzdywr6p.js +0 -9
  602. package/dist/chunks/studio-g5fmf0c1.js +0 -5
  603. package/dist/chunks/studio-g7nse7zb.js +0 -5
  604. package/dist/chunks/studio-geq1ea6k.js +0 -14
  605. package/dist/chunks/studio-ghkb32r8.js +0 -5
  606. package/dist/chunks/studio-ghrhy2y7.js +0 -5
  607. package/dist/chunks/studio-grawhey1.js +0 -5
  608. package/dist/chunks/studio-h0xgswew.js +0 -5
  609. package/dist/chunks/studio-h9c4p2tx.js +0 -5
  610. package/dist/chunks/studio-jyzj5cxs.js +0 -5
  611. package/dist/chunks/studio-mgx8yhnz.js +0 -64
  612. package/dist/chunks/studio-mpb04y1d.js +0 -6
  613. package/dist/chunks/studio-n17mty64.js +0 -5
  614. package/dist/chunks/studio-nwh2eqsk.js +0 -6
  615. package/dist/chunks/studio-q1h883bt.js +0 -16
  616. package/dist/chunks/studio-q4tv82h7.js +0 -9
  617. package/dist/chunks/studio-qpqa7vk3.js +0 -5
  618. package/dist/chunks/studio-qqz8e5gk.js +0 -5
  619. package/dist/chunks/studio-qvasen3f.js +0 -5
  620. package/dist/chunks/studio-rggdb3hm.js +0 -5
  621. package/dist/chunks/studio-sghy936h.js +0 -4
  622. package/dist/chunks/studio-skprc6ef.js +0 -5
  623. package/dist/chunks/studio-tt2nactf.js +0 -5
  624. package/dist/chunks/studio-tyasmc39.js +0 -5
  625. package/dist/chunks/studio-vk9ezads.js +0 -5
  626. package/dist/chunks/studio-vzacdfsc.js +0 -4
  627. package/dist/chunks/studio-w4c0xmrw.js +0 -5
  628. package/dist/chunks/studio-wfjqhhbk.js +0 -5
  629. package/dist/chunks/studio-wgh5kxpj.js +0 -5
  630. package/dist/chunks/studio-xasj0796.js +0 -5
  631. package/dist/chunks/studio-y78s8r2n.js +0 -5
  632. package/dist/chunks/studio-z8w183sh.js +0 -5
  633. package/dist/chunks/studio-zscd9ty4.js +0 -928
  634. package/dist/chunks/studio-zxp13sss.js +0 -7
  635. package/dist/chunks/studio-zygnmm01.js +0 -5
  636. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  637. package/dist/chunks/tabs-jwthg40w.js +0 -4
  638. package/dist/chunks/textfield-spy3hc77.js +0 -4
  639. package/dist/chunks/toast-4d35zd64.js +0 -4
  640. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  641. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  642. package/dist/chunks/tree-h19v1jfz.js +0 -4
  643. package/dist/chunks/tsMode-gr0m4dzr.js +0 -14
  644. package/dist/chunks/workspace-m15qtcqp.js +0 -4
  645. package/dist/chunks/ws-client-nf61frr1.js +0 -4
@@ -18,7 +18,10 @@
18
18
 
19
19
  import { extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
20
20
  import { getReorderDestinationIndex } from "@atlaskit/pragmatic-drag-and-drop-hitbox/util/get-reorder-destination-index";
21
- import type { Edge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
21
+ import type { Edge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/types";
22
+ import type { ElementDragPayload } from "@atlaskit/pragmatic-drag-and-drop/adapter/element-adapter";
23
+ import type { DropTargetRecord } from "@atlaskit/pragmatic-drag-and-drop/types";
24
+ import { isJsonObject } from "@jxsuite/schema/guards";
22
25
  import {
23
26
  activateTab,
24
27
  closePane,
@@ -54,8 +57,13 @@ export interface FileDragData extends Record<string, unknown> {
54
57
 
55
58
  export type TabDropSourceData = TabDragData | FileDragData;
56
59
 
57
- /** A slot in a strip — a chip's edge, or the strip's own empty tail when `tabId` is absent. */
58
- export interface TabSlotTarget extends Record<string, unknown> {
60
+ /**
61
+ * A slot in a strip — a chip's edge, or the strip's own empty tail when `tabId` is absent.
62
+ *
63
+ * Target records are keyed by symbols as well as strings (pragmatic-dnd's `DropTargetRecord`), and
64
+ * a chip's carries one: `attachClosestEdge` stores the edge under a symbol key.
65
+ */
66
+ export interface TabSlotTarget extends Record<string | symbol, unknown> {
59
67
  type: "tab-slot";
60
68
  paneId: string;
61
69
  tabId?: string;
@@ -63,17 +71,17 @@ export interface TabSlotTarget extends Record<string, unknown> {
63
71
  index: number;
64
72
  }
65
73
 
66
- export interface TabSlotRefusedTarget extends Record<string, unknown> {
74
+ export interface TabSlotRefusedTarget extends Record<string | symbol, unknown> {
67
75
  type: "tab-slot-refused";
68
76
  }
69
77
 
70
78
  /** The right band of the last pane's stage, armed only while the grid is under {@link MAX_PANES}. */
71
- export interface PaneEdgeTarget extends Record<string, unknown> {
79
+ export interface PaneEdgeTarget extends Record<string | symbol, unknown> {
72
80
  type: "pane-edge";
73
81
  paneId: string;
74
82
  }
75
83
 
76
- export interface PaneEdgeRefusedTarget extends Record<string, unknown> {
84
+ export interface PaneEdgeRefusedTarget extends Record<string | symbol, unknown> {
77
85
  type: "pane-edge-refused";
78
86
  }
79
87
 
@@ -93,8 +101,11 @@ export type TabDropTarget =
93
101
  * anything else this module has no branch for) is refused at the SOURCE and never reaches a target
94
102
  * closure at all.
95
103
  */
96
- export function isTabDropSource(data: Record<string, unknown>): data is TabDropSourceData {
97
- return data.type === "tab" || (data.type === "file-tree" && data.entryType === "file");
104
+ export function isTabDropSource(data: unknown): data is TabDropSourceData {
105
+ return (
106
+ isJsonObject(data) &&
107
+ (data.type === "tab" || (data.type === "file-tree" && data.entryType === "file"))
108
+ );
98
109
  }
99
110
 
100
111
  /**
@@ -142,7 +153,7 @@ function edgeIndex(target: TabSlotTarget, edge: Edge | null): number {
142
153
  }
143
154
 
144
155
  async function resolveTabSlotDrop(source: TabDropSourceData, target: TabSlotTarget): Promise<void> {
145
- const edge = extractClosestEdge(target as unknown as Record<string | symbol, unknown>);
156
+ const edge = extractClosestEdge(target);
146
157
  if (source.type === "tab") {
147
158
  if (source.paneId === target.paneId) {
148
159
  const pane = paneById(target.paneId);
@@ -202,18 +213,23 @@ async function resolvePaneEdgeDrop(
202
213
  * `undefined` for a drag cancelled off every target — both are legal and both mean nothing landed.
203
214
  */
204
215
  export async function resolveTabDrop(
205
- source: { data: Record<string, unknown> },
206
- target: { data: Record<string, unknown> } | undefined,
216
+ source: Pick<ElementDragPayload, "data">,
217
+ target: Pick<DropTargetRecord, "data"> | undefined,
207
218
  ): Promise<void> {
208
219
  if (!target || !isTabDropSource(source.data)) {
209
220
  return;
210
221
  }
211
222
  const sourceData = source.data;
212
223
  if (target.data.type === "tab-slot") {
224
+ /* SAFETY: a `tab-slot` record is only ever produced by `tab-strip.ts`'s two `getData`
225
+ closures (a chip's and a strip tail's), and both write a string `paneId` and a numeric
226
+ `index` beside the type, with `tabId` only on a chip's. */
213
227
  await resolveTabSlotDrop(sourceData, target.data as TabSlotTarget);
214
228
  return;
215
229
  }
216
230
  if (target.data.type === "pane-edge") {
231
+ /* SAFETY: a `pane-edge` record is only ever produced by `pane-grid.ts`'s edge-zone `getData`,
232
+ whose `PaneEdgeData` pairs that type with a string `paneId`. */
217
233
  await resolvePaneEdgeDrop(sourceData, target.data as PaneEdgeTarget);
218
234
  }
219
235
  // `tab-slot-refused` / `pane-edge-refused` / anything else: nothing.
@@ -62,6 +62,8 @@ import { activeRegistry } from "../commands/active-registry";
62
62
  import { runActiveReported, runReported } from "../commands/run-reported";
63
63
  import { PRESET_LABELS } from "../workspace/pane-derive";
64
64
  import { localeLabel } from "@jxsuite/schema/locale";
65
+ import { isBoolean } from "@jxsuite/schema/guards";
66
+ import type { CommandArgValues } from "../commands/command-args";
65
67
  import { tabOfPane } from "../canvas/canvas-surface";
66
68
  import { mediaDisplayName } from "./shared";
67
69
  import { mountTabStripSurface } from "../surfaces/tab-strip";
@@ -183,8 +185,8 @@ export function mount(host: HTMLElement) {
183
185
  }
184
186
  _drag =
185
187
  source.data.type === "tab"
186
- ? { kind: "tab", tabId: source.data.tabId as string }
187
- : { kind: "file", path: source.data.path as string };
188
+ ? { kind: "tab", tabId: source.data.tabId }
189
+ : { kind: "file", path: source.data.path };
188
190
  // The tail target does not exist until a pane with no tabs is asked to grow one (§14.4's
189
191
  // "Between panes" row; `project` draws it).
190
192
  render();
@@ -198,6 +200,9 @@ export function mount(host: HTMLElement) {
198
200
  }
199
201
  const [target] = location.current.dropTargets;
200
202
  const data = target?.data;
203
+ /* SAFETY: a `tab-slot` record comes only from this module's own two `getData` closures (a
204
+ chip's in `adoptChip`, the tail's in `adoptStrip`), and both write a numeric `index` and a
205
+ string `paneId` beside that type. */
201
206
  _over =
202
207
  data?.type === "tab-slot"
203
208
  ? {
@@ -249,7 +254,7 @@ export function mount(host: HTMLElement) {
249
254
  void tab.session.openedFrom;
250
255
  // The draft pill is on the chip, so the chip has to repaint when the flag changes — reading
251
256
  // The absent key tracks its ADDITION too, which is the transition that matters most.
252
- void tab.doc.content?.frontmatter?.[DRAFT_FIELD];
257
+ void tab.doc.content.frontmatter[DRAFT_FIELD];
253
258
  }
254
259
  // An edit is a commitment: a preview tab with unsaved changes is no longer disposable, and
255
260
  // The dirty flags this effect already tracks are exactly the signal.
@@ -370,8 +375,8 @@ function paint(pane: Pane, host: HTMLElement): void {
370
375
  microtask later — so a strip whose one tab has just come back has no tab marked current at
371
376
  the instant this runs. The flow already knows which chip it wants; asking the tree instead
372
377
  is asking a question we have the answer to, and getting it one tick early. */
373
- ([...strip.children] as HTMLElement[])
374
- .find((chip) => chip.dataset.tab === pane.activeTabId)
378
+ [...strip.children]
379
+ .find((chip) => chip instanceof HTMLElement && chip.dataset.tab === pane.activeTabId)
375
380
  ?.scrollIntoView({ block: "nearest", inline: "nearest" });
376
381
  }
377
382
 
@@ -801,8 +806,8 @@ function onWheel(e: WheelEvent) {
801
806
  if (e.ctrlKey) {
802
807
  return;
803
808
  }
804
- const el = e.currentTarget as HTMLElement;
805
- if (el.scrollWidth <= el.clientWidth) {
809
+ const el = e.currentTarget;
810
+ if (!(el instanceof HTMLElement) || el.scrollWidth <= el.clientWidth) {
806
811
  return;
807
812
  }
808
813
  const delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY;
@@ -832,7 +837,9 @@ export function hiddenTabIds(paneId: string = workspace.activePaneId): string[]
832
837
  const left = strip.scrollLeft;
833
838
  const right = left + strip.clientWidth;
834
839
  const hidden: string[] = [];
835
- const chips = [...strip.querySelectorAll('[part="tab"]')] as HTMLElement[];
840
+ /* Typed, not filtered: a chip's position is what pairs it with `pane.tabOrder[index]`, so dropping
841
+ a node here would shift every later chip onto the wrong tab id. */
842
+ const chips = [...strip.querySelectorAll<HTMLElement>('[part="tab"]')];
836
843
  for (const [index, chip] of chips.entries()) {
837
844
  const id = pane.tabOrder[index];
838
845
  if (id && (chip.offsetLeft < left || chip.offsetLeft + chip.offsetWidth > right)) {
@@ -889,8 +896,8 @@ function openOverflowMenu(pane: Pane, labels: Map<string, string>, anchorEl: HTM
889
896
  place: (box) => ({ x: Math.max(4, anchor.right - box.width), y: anchor.bottom }),
890
897
  placement: "block-end span-inline-start",
891
898
  region: "tab-overflow",
892
- rows: ids.map((id) => ({
893
- checked: (id === pane.activeTabId ? "true" : "false") as "true" | "false",
899
+ rows: ids.map((id): MenuRowProjection => ({
900
+ checked: id === pane.activeTabId ? "true" : "false",
894
901
  destructive: false,
895
902
  disabled: false,
896
903
  dividerAbove: false,
@@ -931,8 +938,8 @@ export function dismissTabContextMenu() {
931
938
  * where it lands (`content/draft-state.ts` says why), so the row offers the flip of what is true
932
939
  * now and {@link statedChecked} reads the current state back out of it for the checkmark.
933
940
  */
934
- function tabRowFacts(tab: Tab): Record<string, unknown> {
935
- const facts: Record<string, unknown> = {};
941
+ function tabRowFacts(tab: Tab): CommandArgValues {
942
+ const facts: CommandArgValues = {};
936
943
  if (collectionOfPath(tab.documentPath)) {
937
944
  facts.draft = !isDraftEntry(entryFields(tab));
938
945
  }
@@ -961,14 +968,14 @@ function tabRowFacts(tab: Tab): Record<string, unknown> {
961
968
  * already knows how to announce — and the five rows that carry no state stay plain `menuitem`s,
962
969
  * which `selects` on the old menu would have made impossible.
963
970
  */
964
- function statedChecked(args: Record<string, unknown>): "true" | "false" | undefined {
971
+ function statedChecked(args: CommandArgValues): "true" | "false" | undefined {
965
972
  const entries = Object.entries(args);
966
- const only = entries.length === 1 ? entries[0] : undefined;
967
- if (!only || typeof only[1] !== "boolean") {
973
+ const value = entries.length === 1 ? entries[0]?.[1] : undefined;
974
+ if (!isBoolean(value)) {
968
975
  return undefined;
969
976
  }
970
977
  // The fact is the state the row would REACH, so the state it is in now is the negation.
971
- return only[1] ? "false" : "true";
978
+ return value ? "false" : "true";
972
979
  }
973
980
 
974
981
  /**
@@ -989,13 +996,11 @@ function placedTabItems(tab: Tab): MenuRowProjection[] {
989
996
  const items: MenuRowProjection[] = [];
990
997
  let group: string | undefined;
991
998
  for (const command of registry.forPlacement("context/tab")) {
992
- const schema = command.args as
993
- | { properties?: Record<string, unknown>; required?: readonly string[] }
994
- | undefined;
999
+ const schema = command.args;
995
1000
  if (!(schema?.required ?? []).every((key) => key in facts)) {
996
1001
  continue;
997
1002
  }
998
- const args: Record<string, unknown> = {};
1003
+ const args: CommandArgValues = {};
999
1004
  for (const key of Object.keys(schema?.properties ?? {})) {
1000
1005
  if (key in facts) {
1001
1006
  args[key] = facts[key];
@@ -1005,21 +1010,26 @@ function placedTabItems(tab: Tab): MenuRowProjection[] {
1005
1010
  ({ group } = command);
1006
1011
  const reason = registry.disabledReason(command.id);
1007
1012
  const checked = statedChecked(args);
1008
- items.push({
1013
+ const row: Omit<MenuRowProjection, "disabled"> = {
1009
1014
  destructive: command.destructive === true,
1010
1015
  dividerAbove,
1011
1016
  id: command.id,
1012
1017
  title: command.title,
1013
- ...(checked === undefined ? {} : { checked }),
1014
- ...(reason === undefined
1018
+ };
1019
+ if (checked !== undefined) {
1020
+ row.checked = checked;
1021
+ }
1022
+ items.push(
1023
+ reason === undefined
1015
1024
  ? {
1025
+ ...row,
1016
1026
  disabled: false,
1017
1027
  run: () => {
1018
1028
  void runReported(registry, command.id, args, "Tabs");
1019
1029
  },
1020
1030
  }
1021
- : { disabled: true, requires: reason }),
1022
- });
1031
+ : { ...row, disabled: true, requires: reason },
1032
+ );
1023
1033
  }
1024
1034
  return items;
1025
1035
  }
@@ -1270,7 +1280,7 @@ export function shouldWarnOnClose(tab: Tab): boolean {
1270
1280
  if (residue) {
1271
1281
  return true;
1272
1282
  }
1273
- const peersHere = state.peers.filter((p) => p.state?.focusedPath === tab.documentPath);
1283
+ const peersHere = state.peers.filter((p) => p.state.focusedPath === tab.documentPath);
1274
1284
  return peersHere.length === 0;
1275
1285
  }
1276
1286
 
@@ -14,6 +14,8 @@
14
14
 
15
15
  import { problemSlug } from "@jxsuite/protocol";
16
16
  import type { OfferedAction, RetryHint } from "@jxsuite/protocol";
17
+ import { isJsonObject, isString } from "@jxsuite/schema/guards";
18
+ import type { JsonValue } from "@jxsuite/schema/types";
17
19
 
18
20
  export interface PlatformErrorInfo {
19
21
  code?: string;
@@ -32,36 +34,44 @@ const RETRY_HINTS = new Set<string>(["reload", "repeat", "none"]);
32
34
  * The offered actions a wire value holds, each one checked: an action needs an `id` and a `label`
33
35
  * to be drawn at all, and anything else it carries is kept only when it has the right type. A
34
36
  * malformed entry is dropped rather than drawn as a button that does nothing.
37
+ *
38
+ * A typed `OfferedAction[]` is accepted too, and checked the same way: it is what a response body
39
+ * cast to its protocol type holds, and nothing has verified that cast.
35
40
  */
36
- export function offeredActions(value: unknown): OfferedAction[] {
41
+ export function offeredActions(
42
+ value: JsonValue | readonly OfferedAction[] | undefined,
43
+ ): OfferedAction[] {
37
44
  if (!Array.isArray(value)) {
38
45
  return [];
39
46
  }
40
- return value.flatMap((entry): OfferedAction[] => {
41
- const raw = entry as Partial<Record<keyof OfferedAction, unknown>> | null;
42
- if (
43
- !raw ||
44
- typeof raw.id !== "string" ||
45
- !raw.id ||
46
- typeof raw.label !== "string" ||
47
- !raw.label
48
- ) {
47
+ const entries: readonly (JsonValue | OfferedAction)[] = value;
48
+ return entries.flatMap((entry): OfferedAction[] => {
49
+ if (!isJsonObject(entry)) {
50
+ return [];
51
+ }
52
+ const { href, id, label, primary } = entry;
53
+ if (!isString(id) || !id || !isString(label) || !label) {
49
54
  return [];
50
55
  }
51
- return [
52
- {
53
- id: raw.id,
54
- label: raw.label,
55
- ...(typeof raw.href === "string" && raw.href ? { href: raw.href } : {}),
56
- ...(raw.primary === true ? { primary: true } : {}),
57
- },
58
- ];
56
+ const action: OfferedAction = { id, label };
57
+ if (isString(href) && href) {
58
+ action.href = href;
59
+ }
60
+ if (primary === true) {
61
+ action.primary = true;
62
+ }
63
+ return [action];
59
64
  });
60
65
  }
61
66
 
67
+ /** Whether a value names one of the retry hints this client knows. */
68
+ function isRetryHint(value: JsonValue | undefined): value is RetryHint {
69
+ return isString(value) && RETRY_HINTS.has(value);
70
+ }
71
+
62
72
  /** The retry hint a wire value names, or undefined when it names none we know. */
63
- export function retryHint(value: unknown): RetryHint | undefined {
64
- return typeof value === "string" && RETRY_HINTS.has(value) ? (value as RetryHint) : undefined;
73
+ export function retryHint(value: JsonValue | undefined): RetryHint | undefined {
74
+ return isRetryHint(value) ? value : undefined;
65
75
  }
66
76
 
67
77
  /**
@@ -74,33 +84,37 @@ function normalizeCode(value: string): string {
74
84
  }
75
85
 
76
86
  /** Machine-readable fields carried by a thrown platform error (empty object when none). */
77
- export function platformErrorInfo(error: unknown): PlatformErrorInfo {
78
- if (!error || typeof error !== "object") {
87
+ export function platformErrorInfo(cause: unknown): PlatformErrorInfo {
88
+ /* An Error carrying the members an adapter assigned onto it passes as a JSON object here: every
89
+ member below is read through a check that accepts any value, so nothing trusts that typing. */
90
+ if (!isJsonObject(cause)) {
79
91
  return {};
80
92
  }
81
- const { actions, code, heading, installUrl, retry, type } = error as {
82
- actions?: unknown;
83
- code?: unknown;
84
- heading?: unknown;
85
- installUrl?: unknown;
86
- retry?: unknown;
87
- type?: unknown;
88
- };
89
- const hint = retryHint(retry);
93
+ const { actions, code, heading, installUrl, retry, type } = cause;
94
+ const info: PlatformErrorInfo = {};
90
95
  // A problem type wins over a legacy code: it is the shape the backend is migrating toward.
91
- const derived = problemSlug(type) ?? (typeof code === "string" ? normalizeCode(code) : null);
92
- return {
93
- ...(derived === null ? {} : { code: derived }),
94
- ...(typeof installUrl === "string" ? { installUrl } : {}),
95
- ...(actions === undefined ? {} : { actions: offeredActions(actions) }),
96
- ...(typeof heading === "string" && heading ? { heading } : {}),
97
- ...(hint === undefined ? {} : { retry: hint }),
98
- };
96
+ const derived = problemSlug(type) ?? (isString(code) ? normalizeCode(code) : null);
97
+ if (derived !== null) {
98
+ info.code = derived;
99
+ }
100
+ if (isString(installUrl)) {
101
+ info.installUrl = installUrl;
102
+ }
103
+ if (actions !== undefined) {
104
+ info.actions = offeredActions(actions);
105
+ }
106
+ if (isString(heading) && heading) {
107
+ info.heading = heading;
108
+ }
109
+ if (isRetryHint(retry)) {
110
+ info.retry = retry;
111
+ }
112
+ return info;
99
113
  }
100
114
 
101
115
  /** The GitHub-App install link when the error is the structured needs-installation 403. */
102
- export function installUrlOf(error: unknown): string | null {
103
- const info = platformErrorInfo(error);
116
+ export function installUrlOf(cause: unknown): string | null {
117
+ const info = platformErrorInfo(cause);
104
118
  return info.code === "needs-installation-access" && info.installUrl ? info.installUrl : null;
105
119
  }
106
120
 
@@ -108,6 +122,6 @@ export function installUrlOf(error: unknown): string | null {
108
122
  * True when the error is an `action-required` refusal (HTTP 403, desktop.md §10.4) — whether the
109
123
  * backend sent the problem type or the legacy `action_required` code.
110
124
  */
111
- export function isActionRequired(error: unknown): boolean {
112
- return platformErrorInfo(error).code === "action-required";
125
+ export function isActionRequired(cause: unknown): boolean {
126
+ return platformErrorInfo(cause).code === "action-required";
113
127
  }
package/src/platform.ts CHANGED
@@ -18,6 +18,7 @@
18
18
  * without ever calling the registrar, and this is the seam both paths share.
19
19
  */
20
20
 
21
+ import { isFunction, isNonNullObject, isString } from "@jxsuite/schema/guards";
21
22
  import type { StudioPlatform } from "./types";
22
23
 
23
24
  /** What a launcher's boot module recorded when its adapter could not be constructed. */
@@ -42,14 +43,16 @@ export interface LauncherSignal {
42
43
  error?: LauncherBootError | undefined;
43
44
  }
44
45
 
45
- const g = globalThis as unknown as {
46
- __jxPlatform?: StudioPlatform;
47
- __jxLauncher?: LauncherSignal;
48
- };
46
+ declare global {
47
+ /** The registered adapter, set by `registerPlatform` or pre-registered by a launcher bundle. */
48
+ var __jxPlatform: StudioPlatform | undefined;
49
+ /** The launcher's boot signal (spec/desktop.md §3.3), when a launcher announced itself. */
50
+ var __jxLauncher: LauncherSignal | undefined;
51
+ }
49
52
 
50
53
  /** @param {StudioPlatform} platform */
51
54
  export function registerPlatform(platform: StudioPlatform) {
52
- g.__jxPlatform = platform;
55
+ globalThis.__jxPlatform = platform;
53
56
  }
54
57
 
55
58
  /**
@@ -58,13 +61,12 @@ export function registerPlatform(platform: StudioPlatform) {
58
61
  * Idempotent, so an error recorded by the first announcer survives a second call.
59
62
  */
60
63
  export function announceLauncher(): LauncherSignal {
61
- g.__jxLauncher ??= {};
62
- return g.__jxLauncher;
64
+ return (globalThis.__jxLauncher ??= {});
63
65
  }
64
66
 
65
67
  /** The launcher signal, when a launcher's boot module announced itself in this window. */
66
68
  export function launcherSignal(): LauncherSignal | undefined {
67
- return g.__jxLauncher;
69
+ return globalThis.__jxLauncher;
68
70
  }
69
71
 
70
72
  // ─── In-flight accounting ─────────────────────────────────────────────────────
@@ -102,6 +104,39 @@ function leave(method: string): void {
102
104
  }
103
105
  }
104
106
 
107
+ /** A promise-like result, recognised the way `await` recognises one: by a callable `then`. */
108
+ function isThenable(value: unknown): value is PromiseLike<unknown> {
109
+ return (isNonNullObject(value) || isFunction(value)) && "then" in value && isFunction(value.then);
110
+ }
111
+
112
+ /**
113
+ * One adapter method, wrapped so each call whose result is a promise counts as in flight under
114
+ * `method` until that promise settles. Any other result is returned untouched.
115
+ *
116
+ * The arguments are `never[]` because the wrapper is reached through the proxy, whose callers are
117
+ * typed by the member's own StudioPlatform signature; it relays whatever they pass, unread.
118
+ */
119
+ function countCalls<R>(
120
+ method: string,
121
+ member: (...args: never[]) => R,
122
+ adapter: StudioPlatform,
123
+ ): (...args: never[]) => R {
124
+ return (...args: never[]): R => {
125
+ const result = member.apply(adapter, args);
126
+ if (!isThenable(result)) {
127
+ return result;
128
+ }
129
+ enter(method);
130
+ const settle = () => {
131
+ leave(method);
132
+ };
133
+ // Both arms: a rejected platform call is a call that FINISHED. Leaving it counted would
134
+ // Wedge every later `idle()` behind an error the caller already handled.
135
+ result.then(settle, settle);
136
+ return result;
137
+ };
138
+ }
139
+
105
140
  /**
106
141
  * Wrap an adapter so every promise-returning member is counted while it is outstanding.
107
142
  *
@@ -111,13 +146,20 @@ function leave(method: string): void {
111
146
  * derive `capability.*`, and a fresh closure per read would allocate on every predicate).
112
147
  */
113
148
  function countingPlatform(platform: StudioPlatform): StudioPlatform {
114
- const wrappers = new Map<PropertyKey, { raw: unknown; wrapper: unknown }>();
149
+ const wrappers = new Map<
150
+ string,
151
+ { raw: StudioPlatform[keyof StudioPlatform]; wrapper: unknown }
152
+ >();
115
153
  return new Proxy(platform, {
116
154
  get(target, property) {
117
- // `this` stays the raw adapter: a proxy receiver would re-enter this trap for every internal
118
- // Property read the method makes, counting nothing and costing everything.
119
- const value = Reflect.get(target, property) as unknown;
120
- if (typeof value !== "function" || typeof property !== "string") {
155
+ /* `this` stays the raw adapter: a proxy receiver would re-enter this trap for every internal
156
+ property read the method makes, counting nothing and costing everything.
157
+ SAFETY: a get trap is asked for any key, not only the ones StudioPlatform declares (`then`
158
+ when the proxy is awaited, inherited `toString`, symbols). An undeclared key reads as
159
+ undefined or an Object.prototype member, which the checks below relay untouched or wrap
160
+ exactly as they would a declared method, so the keyof claim never reaches a caller. */
161
+ const value = target[property as keyof StudioPlatform];
162
+ if (!isFunction(value) || !isString(property)) {
121
163
  return value;
122
164
  }
123
165
  // Keyed by the FUNCTION, not just the name: an adapter whose method is replaced later (a
@@ -127,21 +169,7 @@ function countingPlatform(platform: StudioPlatform): StudioPlatform {
127
169
  if (cached && cached.raw === value) {
128
170
  return cached.wrapper;
129
171
  }
130
- const method = property;
131
- const wrapper = (...args: unknown[]): unknown => {
132
- const result = (value as (...a: unknown[]) => unknown).apply(target, args);
133
- if (typeof (result as PromiseLike<unknown> | null)?.then !== "function") {
134
- return result;
135
- }
136
- enter(method);
137
- const settle = () => {
138
- leave(method);
139
- };
140
- // Both arms: a rejected platform call is a call that FINISHED. Leaving it counted would
141
- // Wedge every later `idle()` behind an error the caller already handled.
142
- (result as PromiseLike<unknown>).then(settle, settle);
143
- return result;
144
- };
172
+ const wrapper = countCalls<ReturnType<typeof value>>(property, value, target);
145
173
  wrappers.set(property, { raw: value, wrapper });
146
174
  return wrapper;
147
175
  },
@@ -153,7 +181,7 @@ let counted: { raw: StudioPlatform; wrapped: StudioPlatform } | null = null;
153
181
 
154
182
  /** @returns {StudioPlatform} */
155
183
  export function getPlatform() {
156
- const raw = g.__jxPlatform;
184
+ const raw = globalThis.__jxPlatform;
157
185
  if (!raw) {
158
186
  throw new Error("No platform registered. Call registerPlatform() before starting Studio.");
159
187
  }
@@ -165,5 +193,5 @@ export function getPlatform() {
165
193
 
166
194
  /** @returns {boolean} */
167
195
  export function hasPlatform() {
168
- return g.__jxPlatform != null;
196
+ return globalThis.__jxPlatform != null;
169
197
  }