@jxsuite/studio 6.1.1 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (785) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  4. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  5. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  6. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  7. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  8. package/dist/chunks/color-area-6rbra5dy.js +4 -0
  9. package/dist/chunks/color-field-gy56c94g.js +4 -0
  10. package/dist/chunks/color-m7r1vk54.js +4 -0
  11. package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
  12. package/dist/chunks/combobox-72h32ejk.js +4 -0
  13. package/dist/chunks/components-r22xca09.js +4 -0
  14. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  15. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  16. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  17. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  18. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  19. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  20. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  21. package/dist/chunks/files-rcn56qvm.js +4 -0
  22. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  23. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  24. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  25. package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
  26. package/dist/chunks/icons-63bjtbs7.js +4 -0
  27. package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
  28. package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
  29. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  30. package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
  31. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  32. package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
  33. package/dist/chunks/index-f0jn7nnp.js +4 -0
  34. package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
  35. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  36. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  37. package/dist/chunks/layers-bgyr11tr.js +4 -0
  38. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  39. package/dist/chunks/listbox-c421cf8c.js +4 -0
  40. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  41. package/dist/chunks/media-library-sq468wts.js +4 -0
  42. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  43. package/dist/chunks/menu-bdpzbfvs.js +4 -0
  44. package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
  45. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  46. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  47. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  48. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  49. package/dist/chunks/parse-v77xtwv7.js +4 -0
  50. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  51. package/dist/chunks/popover-b89sfej7.js +4 -0
  52. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  53. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  54. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  55. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  56. package/dist/chunks/references-9547rg5s.js +4 -0
  57. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  58. package/dist/chunks/select-rzds841e.js +4 -0
  59. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  60. package/dist/chunks/split-c9zfdgxf.js +4 -0
  61. package/dist/chunks/studio-03ct6yfv.js +9 -0
  62. package/dist/chunks/studio-07rcfje3.js +5 -0
  63. package/dist/chunks/studio-3e54qh39.js +7 -0
  64. package/dist/chunks/studio-3exxhz5g.js +5 -0
  65. package/dist/chunks/studio-3q40e3rj.js +5 -0
  66. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  67. package/dist/chunks/studio-3qqjeep5.js +6 -0
  68. package/dist/chunks/studio-43sd2mam.js +4 -0
  69. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  70. package/dist/chunks/studio-58xg6j2q.js +9 -0
  71. package/dist/chunks/studio-5g0rprdt.js +7 -0
  72. package/dist/chunks/studio-6m380wp7.js +5 -0
  73. package/dist/chunks/studio-80jyh1xh.js +4 -0
  74. package/dist/chunks/studio-83mk4bgg.js +9 -0
  75. package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
  76. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  77. package/dist/chunks/studio-8tr6cfrc.js +5 -0
  78. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  79. package/dist/chunks/studio-9tmebf0s.js +5 -0
  80. package/dist/chunks/studio-a2bvaptz.js +5 -0
  81. package/dist/chunks/studio-b7y5mr30.js +5 -0
  82. package/dist/chunks/studio-bavb31r0.js +5 -0
  83. package/dist/chunks/studio-bbe4c90a.js +5 -0
  84. package/dist/chunks/studio-c05wdnt3.js +5 -0
  85. package/dist/chunks/studio-ccv2svc6.js +5 -0
  86. package/dist/chunks/studio-d5grtb9e.js +16 -0
  87. package/dist/chunks/studio-df0baea9.js +5 -0
  88. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  89. package/dist/chunks/studio-e1g64q43.js +5 -0
  90. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  91. package/dist/chunks/studio-ed3xx40h.js +7 -0
  92. package/dist/chunks/studio-f14e1zdj.js +5 -0
  93. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  94. package/dist/chunks/studio-fyh0jc96.js +5 -0
  95. package/dist/chunks/studio-gcxk20n7.js +5 -0
  96. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  97. package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
  98. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  99. package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
  100. package/dist/chunks/studio-k7evxqh4.js +5 -0
  101. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  102. package/dist/chunks/studio-m8g16bgz.js +5 -0
  103. package/dist/chunks/studio-mn0476ag.js +5 -0
  104. package/dist/chunks/studio-mx1smyq0.js +5 -0
  105. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  106. package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
  107. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  108. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  109. package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
  110. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  111. package/dist/chunks/studio-ph84avkf.js +5 -0
  112. package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
  113. package/dist/chunks/studio-q0tccd43.js +5 -0
  114. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  115. package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
  116. package/dist/chunks/studio-qmn1xc24.js +5 -0
  117. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  118. package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
  119. package/dist/chunks/studio-rj9eamf8.js +5 -0
  120. package/dist/chunks/studio-rptgsk96.js +5 -0
  121. package/dist/chunks/studio-rthyg42z.js +928 -0
  122. package/dist/chunks/studio-s19tp1xr.js +5 -0
  123. package/dist/chunks/studio-s32578pn.js +5 -0
  124. package/dist/chunks/studio-svb7yyve.js +5 -0
  125. package/dist/chunks/studio-syreb644.js +5 -0
  126. package/dist/chunks/studio-tf9jryb1.js +10 -0
  127. package/dist/chunks/studio-tfkznv39.js +5 -0
  128. package/dist/chunks/studio-tft6r105.js +5 -0
  129. package/dist/chunks/studio-txf2kysx.js +5 -0
  130. package/dist/chunks/studio-v8867ddv.js +12 -0
  131. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  132. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  133. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  134. package/dist/chunks/studio-wc649wss.js +5 -0
  135. package/dist/chunks/studio-wys23mxz.js +5 -0
  136. package/dist/chunks/studio-x1x167jh.js +5 -0
  137. package/dist/chunks/studio-x9hsze61.js +5 -0
  138. package/dist/chunks/studio-y0n7yxea.js +9 -0
  139. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  140. package/dist/chunks/studio-z97c48fk.js +5 -0
  141. package/dist/chunks/studio-zat62m0c.js +5 -0
  142. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  143. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  144. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  145. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  146. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  147. package/dist/chunks/toast-1gv0h53h.js +4 -0
  148. package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
  149. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  150. package/dist/chunks/tooltip-yypz28gq.js +4 -0
  151. package/dist/chunks/tree-9xa4hm7n.js +4 -0
  152. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  153. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  154. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  155. package/dist/chunks/ws-client-bv552sfx.js +4 -0
  156. package/dist/iframe-entry.js +20 -16
  157. package/dist/manifest.json +77 -63
  158. package/dist/studio.js +106 -107
  159. package/dist/workers/ts.worker.js +3 -3
  160. package/package.json +17 -16
  161. package/src/about/about-modal.ts +4 -3
  162. package/src/account/action-flow.ts +45 -38
  163. package/src/account-status.ts +7 -2
  164. package/src/browse/component-examples.ts +272 -0
  165. package/src/browse/library-commands.ts +64 -104
  166. package/src/browse/library-layouts.ts +270 -53
  167. package/src/browse/library-model.ts +194 -134
  168. package/src/browse/library-pane.ts +748 -440
  169. package/src/browse/library-preview.ts +161 -26
  170. package/src/browse/library-source.ts +308 -41
  171. package/src/browse/preview-root.ts +78 -0
  172. package/src/browse/preview-style.ts +155 -0
  173. package/src/canvas/asset-refs.ts +40 -10
  174. package/src/canvas/asset-resolve.ts +19 -23
  175. package/src/canvas/canvas-helpers.ts +7 -6
  176. package/src/canvas/canvas-live-render.ts +260 -77
  177. package/src/canvas/canvas-origin.ts +37 -12
  178. package/src/canvas/canvas-page-context.ts +112 -0
  179. package/src/canvas/canvas-patcher.ts +30 -30
  180. package/src/canvas/canvas-perf.ts +11 -5
  181. package/src/canvas/canvas-render.ts +175 -148
  182. package/src/canvas/canvas-surface.ts +5 -3
  183. package/src/canvas/canvas-utils.ts +147 -61
  184. package/src/canvas/dialog-path.ts +9 -4
  185. package/src/canvas/dialog-state.ts +1 -2
  186. package/src/canvas/diff-marks.ts +9 -16
  187. package/src/canvas/diff-toolbar.ts +8 -7
  188. package/src/canvas/edit-width-drag.ts +4 -1
  189. package/src/canvas/edit-width.ts +1 -3
  190. package/src/canvas/iframe-channel.ts +27 -13
  191. package/src/canvas/iframe-drop.ts +120 -12
  192. package/src/canvas/iframe-editable-root.ts +29 -16
  193. package/src/canvas/iframe-entry.ts +104 -75
  194. package/src/canvas/iframe-eval.ts +73 -49
  195. package/src/canvas/iframe-host.ts +269 -158
  196. package/src/canvas/iframe-inline-edit.ts +49 -30
  197. package/src/canvas/iframe-insert.ts +5 -4
  198. package/src/canvas/iframe-interaction.ts +30 -25
  199. package/src/canvas/iframe-keys.ts +11 -0
  200. package/src/canvas/iframe-overlay.ts +1 -1
  201. package/src/canvas/iframe-patch.ts +25 -21
  202. package/src/canvas/iframe-position.ts +12 -6
  203. package/src/canvas/iframe-protocol.ts +36 -21
  204. package/src/canvas/iframe-render.ts +84 -35
  205. package/src/canvas/iframe-slash.ts +24 -11
  206. package/src/canvas/iframe-subtree.ts +10 -3
  207. package/src/canvas/npm-modules.ts +22 -0
  208. package/src/canvas/path-mapping.ts +19 -12
  209. package/src/canvas/popover-path.ts +7 -3
  210. package/src/canvas/popover-state.ts +1 -2
  211. package/src/canvas/preview-navigate.ts +16 -0
  212. package/src/canvas/repeater-sources.ts +200 -0
  213. package/src/canvas/serialize-scope.ts +13 -5
  214. package/src/canvas/stage-scrollbar.ts +7 -2
  215. package/src/canvas/surface-registry.ts +27 -3
  216. package/src/collab/collab-commands.ts +7 -2
  217. package/src/collab/collab-session.ts +84 -45
  218. package/src/collab/collab-state.ts +4 -3
  219. package/src/collab/monaco-binding.ts +16 -13
  220. package/src/collab/monaco-cursors.ts +5 -2
  221. package/src/commands/app-commands.ts +16 -6
  222. package/src/commands/budget.ts +13 -11
  223. package/src/commands/command-args.ts +103 -71
  224. package/src/commands/context.ts +55 -28
  225. package/src/commands/defaults.ts +69 -45
  226. package/src/commands/keymap.ts +56 -43
  227. package/src/commands/levels.ts +14 -8
  228. package/src/commands/live-context.ts +9 -7
  229. package/src/commands/reference.ts +2 -1
  230. package/src/commands/registry.ts +22 -11
  231. package/src/commands/run-reported.ts +15 -10
  232. package/src/component-props.ts +46 -30
  233. package/src/content/collection-match.ts +11 -9
  234. package/src/content/collection-pages.ts +412 -0
  235. package/src/content/content-collections.ts +270 -0
  236. package/src/content/draft-state.ts +4 -3
  237. package/src/content/entry-commands.ts +54 -62
  238. package/src/content/entry-editor.ts +137 -32
  239. package/src/content/entry-fields.ts +25 -8
  240. package/src/content/entry-inspector.ts +225 -0
  241. package/src/content/entry-model.ts +38 -15
  242. package/src/content/entry-open.ts +80 -0
  243. package/src/content/entry-summaries.ts +440 -0
  244. package/src/content/file-record-ids.ts +80 -0
  245. package/src/content/file-records.ts +125 -0
  246. package/src/content/page-summaries.ts +129 -0
  247. package/src/content/record-entry.ts +201 -0
  248. package/src/content/writing-banner.ts +177 -0
  249. package/src/create/add-new-commands.ts +185 -0
  250. package/src/create/add-new-flow.ts +1116 -0
  251. package/src/create/add-new.ts +1014 -0
  252. package/src/create/element-name.ts +121 -0
  253. package/src/editor/canvas-context-menu.ts +1 -2
  254. package/src/editor/canvas-slash-bridge.ts +3 -6
  255. package/src/editor/content-slice.ts +16 -14
  256. package/src/editor/context-menu.ts +35 -22
  257. package/src/editor/convert-targets.ts +30 -35
  258. package/src/editor/convert-to-component.ts +78 -48
  259. package/src/editor/convert-to-repeater.ts +34 -22
  260. package/src/editor/editable-tags.ts +17 -2
  261. package/src/editor/file-drop-action.ts +29 -22
  262. package/src/editor/inline-edit-apply.ts +79 -17
  263. package/src/editor/inline-edit.ts +76 -50
  264. package/src/editor/inline-format.ts +59 -56
  265. package/src/editor/inline-link.ts +40 -15
  266. package/src/editor/insert-component.ts +91 -0
  267. package/src/editor/insert-zone-action.ts +14 -5
  268. package/src/editor/merge-tags.ts +58 -19
  269. package/src/editor/repeater-scope.ts +39 -28
  270. package/src/editor/shortcuts.ts +76 -42
  271. package/src/editor/slash-menu.ts +52 -14
  272. package/src/files/asset-versions.ts +4 -4
  273. package/src/files/components.ts +89 -20
  274. package/src/files/elements.ts +5 -6
  275. package/src/files/file-ops.ts +92 -41
  276. package/src/files/files.ts +248 -239
  277. package/src/files/fs-events.ts +18 -7
  278. package/src/files/media-meta.ts +97 -2
  279. package/src/files/media-paths.ts +3 -0
  280. package/src/files/media-types.ts +55 -0
  281. package/src/files/media-upload.ts +209 -52
  282. package/src/files/new-file-name.ts +156 -0
  283. package/src/files/serialize-document.ts +15 -5
  284. package/src/format/constraints.ts +1 -1
  285. package/src/format/convert-file.ts +27 -13
  286. package/src/format/format-choices.ts +2 -1
  287. package/src/format/format-host.ts +91 -50
  288. package/src/github/github-auth-status.ts +27 -3
  289. package/src/github/github-auth.ts +21 -11
  290. package/src/github/github-publish.ts +28 -23
  291. package/src/grid/cell-editors.ts +46 -31
  292. package/src/grid/cell-popovers.ts +5 -3
  293. package/src/grid/edit-buffer.ts +10 -9
  294. package/src/grid/grid-controller.ts +25 -23
  295. package/src/grid/grid-layout.ts +21 -5
  296. package/src/grid/grid-open.ts +3 -33
  297. package/src/grid/grid-panel.ts +65 -6
  298. package/src/grid/grid-reveal.ts +34 -0
  299. package/src/grid/grid-source.ts +9 -31
  300. package/src/grid/grid-view.ts +45 -23
  301. package/src/grid/redirects-grid.ts +14 -5
  302. package/src/grid/redirects.ts +16 -14
  303. package/src/grid/schema-columns.ts +25 -19
  304. package/src/grid/sources/connector-source.ts +47 -20
  305. package/src/grid/sources/content-source.ts +100 -31
  306. package/src/grid/sources/csv-file-source.ts +2 -2
  307. package/src/grid/tabulator-tables.d.ts +61 -34
  308. package/src/hosting/document.ts +2 -2
  309. package/src/hosting/stage.ts +7 -7
  310. package/src/i18n/i18n-commands.ts +3 -3
  311. package/src/media/media-commands.ts +181 -0
  312. package/src/media/media-library-model.ts +232 -0
  313. package/src/media/media-library.ts +1283 -0
  314. package/src/media/media-pane.ts +51 -20
  315. package/src/new-project/add-repo-modal.ts +20 -19
  316. package/src/new-project/import-tab.ts +10 -14
  317. package/src/new-project/location-fields.ts +2 -1
  318. package/src/new-project/new-project-modal.ts +12 -9
  319. package/src/packages/jxsuite-update.ts +4 -3
  320. package/src/packages/pull-package-sync.ts +26 -25
  321. package/src/page-params.ts +97 -68
  322. package/src/panels/activity-panel.ts +38 -14
  323. package/src/panels/ai-chat/attached-context.ts +13 -7
  324. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  325. package/src/panels/ai-chat/chat-view.ts +80 -73
  326. package/src/panels/ai-chat/composer.ts +30 -33
  327. package/src/panels/ai-chat/sessions-view.ts +1 -2
  328. package/src/panels/ai-panel.ts +23 -20
  329. package/src/panels/block-action-bar.ts +57 -46
  330. package/src/panels/bottom-dock.ts +5 -3
  331. package/src/panels/canvas-dnd-bridge.ts +36 -26
  332. package/src/panels/chat-panel.ts +6 -6
  333. package/src/panels/collections-panel.ts +306 -0
  334. package/src/panels/component-preview.ts +35 -13
  335. package/src/panels/data-explorer.ts +63 -26
  336. package/src/panels/data-grid.ts +18 -11
  337. package/src/panels/dnd.ts +115 -138
  338. package/src/panels/editors.ts +52 -21
  339. package/src/panels/elements-panel.ts +19 -5
  340. package/src/panels/empty-state.ts +2 -2
  341. package/src/panels/events-panel.ts +84 -69
  342. package/src/panels/formula-workspace.ts +78 -54
  343. package/src/panels/frontmatter-fields.ts +33 -28
  344. package/src/panels/git-diff-open.ts +10 -6
  345. package/src/panels/head-panel.ts +488 -202
  346. package/src/panels/i18n-panel.ts +20 -12
  347. package/src/panels/imports-panel.ts +25 -47
  348. package/src/panels/jump-bar.ts +75 -31
  349. package/src/panels/layers-panel.ts +130 -101
  350. package/src/panels/left-panel.ts +25 -11
  351. package/src/panels/navigator-panels.ts +23 -11
  352. package/src/panels/pane-context.ts +140 -49
  353. package/src/panels/pane-grid.ts +55 -26
  354. package/src/panels/panel-registry.ts +36 -46
  355. package/src/panels/properties-panel.ts +182 -124
  356. package/src/panels/quick-search.ts +53 -31
  357. package/src/panels/right-panel.ts +201 -45
  358. package/src/panels/seo-modal.ts +54 -125
  359. package/src/panels/settings-menu.ts +63 -61
  360. package/src/panels/settings-pane.ts +268 -162
  361. package/src/panels/signals-panel.ts +156 -135
  362. package/src/panels/site-model.ts +367 -0
  363. package/src/panels/site-panel.ts +638 -0
  364. package/src/panels/statement-editor.ts +230 -140
  365. package/src/panels/style-panel.ts +253 -206
  366. package/src/panels/style-utils.ts +114 -51
  367. package/src/panels/stylebook-doc.ts +195 -60
  368. package/src/panels/stylebook-layers-panel.ts +48 -89
  369. package/src/panels/stylebook-panel.ts +60 -27
  370. package/src/panels/styles-panel.ts +327 -0
  371. package/src/panels/tab-drop.ts +27 -11
  372. package/src/panels/tab-strip.ts +143 -49
  373. package/src/platform-errors.ts +57 -43
  374. package/src/platform.ts +59 -31
  375. package/src/platforms/cloud.ts +373 -176
  376. package/src/platforms/default-platform.ts +14 -8
  377. package/src/platforms/devserver.ts +180 -142
  378. package/src/platforms/read-batcher.ts +16 -8
  379. package/src/project-list.ts +2 -1
  380. package/src/publish/deploy-checklist.ts +20 -9
  381. package/src/publish/pages-service.ts +66 -27
  382. package/src/publish/publish-changes.ts +491 -0
  383. package/src/publish/publish-commands.ts +88 -22
  384. package/src/publish/publish-ids.ts +49 -0
  385. package/src/publish/publish-panel.ts +10 -6
  386. package/src/publish/publish-quick.ts +148 -0
  387. package/src/publish/publish-workspace.ts +926 -0
  388. package/src/publish/source-control.ts +907 -0
  389. package/src/recent-projects.ts +15 -8
  390. package/src/resize-edges.ts +26 -36
  391. package/src/services/a11y-report.ts +26 -19
  392. package/src/services/agent-seed.ts +23 -11
  393. package/src/services/ai-ask.ts +9 -12
  394. package/src/services/ai-command-tools.ts +68 -62
  395. package/src/services/ai-import-tools.ts +80 -67
  396. package/src/services/ai-models.ts +17 -13
  397. package/src/services/ai-project-tools.ts +68 -32
  398. package/src/services/ai-session-store.ts +19 -10
  399. package/src/services/ai-system-prompt.ts +46 -20
  400. package/src/services/ai-tools.ts +71 -27
  401. package/src/services/ai-write-report.ts +20 -12
  402. package/src/services/ai-writes.ts +4 -4
  403. package/src/services/automation.ts +74 -51
  404. package/src/services/cem-export.ts +149 -58
  405. package/src/services/cf-settings.ts +4 -4
  406. package/src/services/clock.ts +6 -1
  407. package/src/services/code-services.ts +37 -31
  408. package/src/services/connection.ts +2 -2
  409. package/src/services/context-manager.ts +14 -10
  410. package/src/services/context-resolver.ts +20 -8
  411. package/src/services/data-service.ts +19 -15
  412. package/src/services/directory-picker.ts +20 -14
  413. package/src/services/document-assistant.ts +39 -19
  414. package/src/services/gated-registry.ts +10 -6
  415. package/src/services/harness/chat-reducer.ts +23 -1
  416. package/src/services/import-client.ts +91 -38
  417. package/src/services/import-seed.ts +8 -2
  418. package/src/services/jx-validate.ts +28 -31
  419. package/src/services/live-preview.ts +0 -0
  420. package/src/services/live-surfaces.ts +6 -3
  421. package/src/services/model-uri.ts +10 -2
  422. package/src/services/module-preloads.ts +12 -8
  423. package/src/services/monaco-buffer.ts +43 -24
  424. package/src/services/monaco-lazy.ts +7 -8
  425. package/src/services/monaco-setup.ts +23 -16
  426. package/src/services/notify.ts +44 -17
  427. package/src/services/popover-report.ts +25 -10
  428. package/src/services/preview-eval.ts +20 -8
  429. package/src/services/profile.ts +13 -6
  430. package/src/services/project-path.ts +13 -10
  431. package/src/services/references.ts +0 -0
  432. package/src/services/render-critic.ts +29 -9
  433. package/src/services/settings/definitions.ts +25 -14
  434. package/src/services/settings/kernel.ts +13 -4
  435. package/src/services/settings/write-queue.ts +9 -9
  436. package/src/services/token-lint.ts +12 -10
  437. package/src/services/tool-executor.ts +17 -5
  438. package/src/services/tool-outcomes.ts +44 -24
  439. package/src/services/trusted-types.ts +24 -7
  440. package/src/settings/contexts-section.ts +11 -8
  441. package/src/settings/contributed-section.ts +128 -70
  442. package/src/settings/css-vars-editor.ts +119 -32
  443. package/src/settings/defs-editor.ts +38 -35
  444. package/src/settings/developer-panels.ts +43 -0
  445. package/src/settings/extension-rows.ts +16 -8
  446. package/src/settings/extension-sections.ts +42 -14
  447. package/src/settings/extensions-section.ts +4 -1
  448. package/src/settings/general-settings.ts +101 -28
  449. package/src/settings/locales-section.ts +20 -12
  450. package/src/settings/preferences-dialog.ts +17 -7
  451. package/src/settings/preferences-keymap.ts +7 -5
  452. package/src/settings/preferences-sections.ts +11 -5
  453. package/src/settings/project-sections.ts +28 -11
  454. package/src/settings/schema-field-ui.ts +12 -1
  455. package/src/settings/section-registry.ts +116 -11
  456. package/src/settings/settings-dialog.ts +192 -0
  457. package/src/settings/settings-document.ts +186 -166
  458. package/src/shell/tree.ts +6 -5
  459. package/src/shell.ts +536 -477
  460. package/src/site-context.ts +101 -32
  461. package/src/state.ts +68 -57
  462. package/src/store.ts +54 -34
  463. package/src/studio.ts +219 -116
  464. package/src/style/live-preview.ts +1 -1
  465. package/src/style/project-styles.ts +40 -7
  466. package/src/style/stylebook-specimens.ts +89 -0
  467. package/src/style/stylebook-target.ts +26 -0
  468. package/src/style/tag-inheritance.ts +105 -0
  469. package/src/style/token-ref.ts +5 -4
  470. package/src/style/variables-focus.ts +61 -0
  471. package/src/style/variables-view.ts +235 -0
  472. package/src/surfaces/about.ts +18 -19
  473. package/src/surfaces/add-new.json +1482 -0
  474. package/src/surfaces/add-new.ts +325 -0
  475. package/src/surfaces/add-repo.ts +17 -19
  476. package/src/surfaces/ai-chat.ts +33 -38
  477. package/src/surfaces/ai-credentials-form.ts +6 -16
  478. package/src/surfaces/ai-managed-connect.ts +3 -4
  479. package/src/surfaces/ai-model-picker.ts +3 -5
  480. package/src/surfaces/block-action-bar.ts +22 -11
  481. package/src/surfaces/boot-failure.json +4 -3
  482. package/src/surfaces/boot-failure.ts +4 -5
  483. package/src/surfaces/bottom-dock.json +1 -1
  484. package/src/surfaces/bottom-dock.ts +9 -18
  485. package/src/surfaces/canvas-stage.json +30 -19
  486. package/src/surfaces/canvas-stage.ts +17 -16
  487. package/src/surfaces/cf-account-picker.ts +17 -18
  488. package/src/surfaces/collections-panel.json +615 -0
  489. package/src/surfaces/collections-panel.ts +168 -0
  490. package/src/surfaces/commandbar.json +241 -96
  491. package/src/surfaces/commandbar.ts +145 -105
  492. package/src/surfaces/convert-repeater.ts +17 -19
  493. package/src/surfaces/data-actions.ts +9 -7
  494. package/src/surfaces/dialog.ts +26 -28
  495. package/src/surfaces/diff-toolbar.ts +9 -7
  496. package/src/surfaces/empty-state.json +1 -1
  497. package/src/surfaces/empty-state.ts +7 -10
  498. package/src/surfaces/entry-editor.json +136 -0
  499. package/src/surfaces/entry-editor.ts +35 -11
  500. package/src/surfaces/entry-inspector.json +371 -0
  501. package/src/surfaces/entry-inspector.ts +143 -0
  502. package/src/surfaces/expression-editor.ts +11 -25
  503. package/src/surfaces/files-panel.ts +27 -14
  504. package/src/surfaces/formula-palette.ts +4 -5
  505. package/src/surfaces/github-auth.ts +16 -20
  506. package/src/surfaces/github-publish.ts +17 -22
  507. package/src/surfaces/grid-cell.ts +30 -31
  508. package/src/surfaces/grid-open.ts +10 -14
  509. package/src/surfaces/grid-panel.ts +13 -9
  510. package/src/surfaces/grid-replace.ts +13 -13
  511. package/src/surfaces/grid-views.ts +15 -18
  512. package/src/surfaces/inspector-dock.json +162 -14
  513. package/src/surfaces/inspector-dock.ts +59 -31
  514. package/src/surfaces/jump-bar.ts +5 -6
  515. package/src/surfaces/jxsuite-update.ts +16 -22
  516. package/src/surfaces/library-pane.json +670 -437
  517. package/src/surfaces/library-pane.ts +111 -77
  518. package/src/surfaces/logic-panel.ts +17 -30
  519. package/src/surfaces/logic-workspace.ts +13 -15
  520. package/src/surfaces/media-browser.json +62 -6
  521. package/src/surfaces/media-browser.ts +26 -11
  522. package/src/surfaces/media-field.json +1 -1
  523. package/src/surfaces/media-field.ts +4 -5
  524. package/src/surfaces/media-library.json +1586 -0
  525. package/src/surfaces/media-library.ts +282 -0
  526. package/src/surfaces/media-pane.ts +8 -7
  527. package/src/surfaces/media-pick-dialog.json +71 -0
  528. package/src/surfaces/media-pick-dialog.ts +132 -0
  529. package/src/surfaces/menu.ts +47 -23
  530. package/src/surfaces/navigator-dock.ts +11 -12
  531. package/src/surfaces/new-project.ts +27 -26
  532. package/src/surfaces/pane-context.json +144 -77
  533. package/src/surfaces/pane-context.ts +44 -25
  534. package/src/surfaces/pane-grid.ts +15 -10
  535. package/src/surfaces/panel-activity.ts +5 -6
  536. package/src/surfaces/panel-data.ts +3 -4
  537. package/src/surfaces/panel-deploy-checklist.json +12 -6
  538. package/src/surfaces/panel-deploy-checklist.ts +8 -7
  539. package/src/surfaces/panel-elements.ts +5 -7
  540. package/src/surfaces/panel-i18n.ts +5 -7
  541. package/src/surfaces/panel-imports.ts +6 -13
  542. package/src/surfaces/panel-outline.ts +25 -19
  543. package/src/surfaces/panel-page.json +72 -2
  544. package/src/surfaces/panel-page.ts +49 -25
  545. package/src/surfaces/panel-problems.ts +5 -7
  546. package/src/surfaces/panel-signals.json +1 -1
  547. package/src/surfaces/panel-signals.ts +25 -39
  548. package/src/surfaces/panel-stylebook-layers.json +71 -204
  549. package/src/surfaces/panel-stylebook-layers.ts +5 -29
  550. package/src/surfaces/preferences.json +120 -48
  551. package/src/surfaces/preferences.ts +29 -11
  552. package/src/surfaces/progress-modal.ts +15 -9
  553. package/src/surfaces/properties-panel.json +1 -1
  554. package/src/surfaces/properties-panel.ts +20 -42
  555. package/src/surfaces/publish-quick.json +428 -0
  556. package/src/surfaces/publish-quick.ts +165 -0
  557. package/src/surfaces/publish-workspace.json +2892 -0
  558. package/src/surfaces/publish-workspace.ts +391 -0
  559. package/src/surfaces/publish.ts +18 -18
  560. package/src/surfaces/push-plan.ts +7 -8
  561. package/src/surfaces/rail.json +1 -159
  562. package/src/surfaces/rail.ts +22 -79
  563. package/src/surfaces/reference-field.ts +11 -15
  564. package/src/surfaces/schema-builder.ts +16 -22
  565. package/src/surfaces/schema-form.json +10 -2
  566. package/src/surfaces/schema-form.ts +17 -25
  567. package/src/surfaces/secret-field.ts +9 -6
  568. package/src/surfaces/seo.json +1 -1
  569. package/src/surfaces/seo.ts +21 -15
  570. package/src/surfaces/settings-contexts.ts +9 -7
  571. package/src/surfaces/settings-contributed.json +5 -5
  572. package/src/surfaces/settings-contributed.ts +32 -12
  573. package/src/surfaces/settings-css-vars.json +44 -36
  574. package/src/surfaces/settings-css-vars.ts +82 -16
  575. package/src/surfaces/settings-defs.json +2 -2
  576. package/src/surfaces/settings-defs.ts +17 -21
  577. package/src/surfaces/settings-deploy.json +2 -15
  578. package/src/surfaces/settings-deploy.ts +9 -16
  579. package/src/surfaces/settings-dialog.json +51 -0
  580. package/src/surfaces/settings-dialog.ts +169 -0
  581. package/src/surfaces/settings-extensions.ts +5 -6
  582. package/src/surfaces/settings-head.ts +33 -39
  583. package/src/surfaces/settings-locales.ts +8 -20
  584. package/src/surfaces/settings-overview.json +3 -3
  585. package/src/surfaces/settings-overview.ts +14 -8
  586. package/src/surfaces/settings-packages.ts +8 -7
  587. package/src/surfaces/settings-pane.json +269 -46
  588. package/src/surfaces/settings-pane.ts +88 -36
  589. package/src/surfaces/settings-rawjson.ts +5 -6
  590. package/src/surfaces/shell.json +2 -1
  591. package/src/surfaces/shell.ts +1 -2
  592. package/src/surfaces/site-panel.json +1029 -0
  593. package/src/surfaces/site-panel.ts +233 -0
  594. package/src/surfaces/slash-menu.json +63 -21
  595. package/src/surfaces/slash-menu.ts +42 -9
  596. package/src/surfaces/statements.ts +13 -18
  597. package/src/surfaces/statusbar.ts +56 -29
  598. package/src/surfaces/style-panel.ts +18 -31
  599. package/src/surfaces/stylebook-chrome.ts +3 -5
  600. package/src/surfaces/styles-panel.json +735 -0
  601. package/src/surfaces/styles-panel.ts +195 -0
  602. package/src/surfaces/styles-variables.json +149 -0
  603. package/src/surfaces/styles-variables.ts +145 -0
  604. package/src/surfaces/tab-strip.json +4 -4
  605. package/src/surfaces/tab-strip.ts +14 -13
  606. package/src/surfaces/target-line.ts +6 -7
  607. package/src/surfaces/welcome.ts +6 -8
  608. package/src/surfaces/writing-banner.json +94 -0
  609. package/src/surfaces/writing-banner.ts +80 -0
  610. package/src/tabs/bare-repeaters.ts +101 -0
  611. package/src/tabs/patch-ops.ts +4 -3
  612. package/src/tabs/project-config.ts +32 -21
  613. package/src/tabs/selection.ts +36 -8
  614. package/src/tabs/tab.ts +99 -48
  615. package/src/tabs/transact.ts +98 -53
  616. package/src/types.ts +53 -43
  617. package/src/ui/ai-credentials-form.ts +10 -13
  618. package/src/ui/ai-model-picker.ts +3 -3
  619. package/src/ui/cf-account-picker.ts +7 -9
  620. package/src/ui/color-selector.ts +9 -5
  621. package/src/ui/dynamic-slot.ts +7 -8
  622. package/src/ui/expression-editor.ts +112 -105
  623. package/src/ui/form-controls.ts +104 -56
  624. package/src/ui/formula-catalog.ts +239 -230
  625. package/src/ui/formula-chips.ts +33 -18
  626. package/src/ui/layers.ts +57 -31
  627. package/src/ui/media-picker.ts +300 -47
  628. package/src/ui/popover-surface.ts +20 -12
  629. package/src/ui/progress-modal.ts +13 -8
  630. package/src/ui/regions.ts +14 -12
  631. package/src/ui/schema-form.ts +372 -97
  632. package/src/ui/surface.ts +71 -8
  633. package/src/ui/timing.ts +9 -0
  634. package/src/ui/value-source.ts +44 -31
  635. package/src/ui/virtual-window.ts +29 -3
  636. package/src/utils/base64.ts +6 -4
  637. package/src/utils/edit-display.ts +366 -111
  638. package/src/utils/element-selectors.ts +3 -2
  639. package/src/utils/google-fonts.ts +15 -14
  640. package/src/utils/inherited-style.ts +18 -20
  641. package/src/utils/link-target.ts +1 -1
  642. package/src/utils/local-day.ts +18 -0
  643. package/src/utils/preview-format.ts +25 -3
  644. package/src/utils/strip-events.ts +49 -22
  645. package/src/utils/studio-utils.ts +29 -14
  646. package/src/view.ts +2 -3
  647. package/src/workspace/pane-derive.ts +14 -16
  648. package/src/workspace/session.ts +81 -50
  649. package/src/workspace/tab-workspace.ts +137 -0
  650. package/src/workspace/workspace-back.ts +189 -0
  651. package/src/workspace/workspace-home.ts +133 -0
  652. package/src/workspace/workspace-ids.ts +129 -0
  653. package/src/workspace/workspace-switch.ts +372 -0
  654. package/src/workspace/workspace.ts +165 -47
  655. package/styles/shell-frame.css +30 -7
  656. package/styles/shell-frame.json +15 -3
  657. package/dist/chunks/2020-va2wwra4.js +0 -4
  658. package/dist/chunks/adapter-f93pafd7.js +0 -4
  659. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  660. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  661. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  662. package/dist/chunks/color-field-embq5ctg.js +0 -4
  663. package/dist/chunks/color-fpezvnkt.js +0 -4
  664. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  665. package/dist/chunks/combobox-773hdzyj.js +0 -4
  666. package/dist/chunks/components-ax2f1fnn.js +0 -4
  667. package/dist/chunks/content-source-108aqtk1.js +0 -4
  668. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  669. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  670. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  671. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  672. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  673. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  674. package/dist/chunks/files-44vp8a2s.js +0 -4
  675. package/dist/chunks/format-host-7q1petb9.js +0 -4
  676. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  677. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  678. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  679. package/dist/chunks/icons-p44xhjf0.js +0 -4
  680. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  681. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  682. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  683. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  684. package/dist/chunks/index-wkyfjeqz.js +0 -4
  685. package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
  686. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  687. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  688. package/dist/chunks/layers-xd92fg8d.js +0 -4
  689. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  690. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  691. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  692. package/dist/chunks/menu-37d07z9m.js +0 -4
  693. package/dist/chunks/menu-5c55ea3d.js +0 -4
  694. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  695. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  696. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  697. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  698. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  699. package/dist/chunks/parse-897fvqah.js +0 -4
  700. package/dist/chunks/platform-v1qctbe6.js +0 -4
  701. package/dist/chunks/popover-8htra4er.js +0 -4
  702. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  703. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  704. package/dist/chunks/references-gmqp82fs.js +0 -4
  705. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  706. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  707. package/dist/chunks/select-n3v7gwas.js +0 -4
  708. package/dist/chunks/split-pff8f3ze.js +0 -4
  709. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  710. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  711. package/dist/chunks/studio-1b04pd0j.js +0 -64
  712. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  713. package/dist/chunks/studio-4tanh828.js +0 -5
  714. package/dist/chunks/studio-55h4mstj.js +0 -4
  715. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  716. package/dist/chunks/studio-60dqgb0c.js +0 -5
  717. package/dist/chunks/studio-61dp09qg.js +0 -9
  718. package/dist/chunks/studio-63epcrj2.js +0 -5
  719. package/dist/chunks/studio-74k29dy9.js +0 -5
  720. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  721. package/dist/chunks/studio-7zx31knw.js +0 -9
  722. package/dist/chunks/studio-8bxk97km.js +0 -5
  723. package/dist/chunks/studio-933e30n4.js +0 -5
  724. package/dist/chunks/studio-98wnwhbg.js +0 -5
  725. package/dist/chunks/studio-9mccjwjh.js +0 -14
  726. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  727. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  728. package/dist/chunks/studio-e81q1vb9.js +0 -5
  729. package/dist/chunks/studio-epgrmqqm.js +0 -5
  730. package/dist/chunks/studio-ery42sqr.js +0 -4
  731. package/dist/chunks/studio-g1shz58g.js +0 -5
  732. package/dist/chunks/studio-gf0fz03c.js +0 -5
  733. package/dist/chunks/studio-gjtpe62q.js +0 -6
  734. package/dist/chunks/studio-gkskhg7m.js +0 -5
  735. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  736. package/dist/chunks/studio-j03zga3y.js +0 -9
  737. package/dist/chunks/studio-jhpxeckz.js +0 -5
  738. package/dist/chunks/studio-k01r7ykp.js +0 -5
  739. package/dist/chunks/studio-kk7h30ne.js +0 -7
  740. package/dist/chunks/studio-kt1zqney.js +0 -5
  741. package/dist/chunks/studio-m3cwhvye.js +0 -5
  742. package/dist/chunks/studio-mcayt6hz.js +0 -5
  743. package/dist/chunks/studio-myjcghv3.js +0 -5
  744. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  745. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  746. package/dist/chunks/studio-nj5a01jy.js +0 -928
  747. package/dist/chunks/studio-pcgz8heb.js +0 -5
  748. package/dist/chunks/studio-qcsq0t15.js +0 -5
  749. package/dist/chunks/studio-qkstvve9.js +0 -5
  750. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  751. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  752. package/dist/chunks/studio-s8dmmz66.js +0 -5
  753. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  754. package/dist/chunks/studio-szsjbj0g.js +0 -5
  755. package/dist/chunks/studio-t1xzawhr.js +0 -16
  756. package/dist/chunks/studio-tdcprbqb.js +0 -5
  757. package/dist/chunks/studio-vrmcjf9g.js +0 -7
  758. package/dist/chunks/studio-vyc0b4he.js +0 -10
  759. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  760. package/dist/chunks/studio-w3hskzqk.js +0 -5
  761. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  762. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  763. package/dist/chunks/studio-y6n42tgs.js +0 -5
  764. package/dist/chunks/studio-yb560vxr.js +0 -5
  765. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  766. package/dist/chunks/studio-yw05w8f0.js +0 -7
  767. package/dist/chunks/studio-z16sgavc.js +0 -5
  768. package/dist/chunks/studio-zey7zsdw.js +0 -12
  769. package/dist/chunks/studio-zyqn40w4.js +0 -5
  770. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  771. package/dist/chunks/tabs-jwthg40w.js +0 -4
  772. package/dist/chunks/textfield-spy3hc77.js +0 -4
  773. package/dist/chunks/toast-4d35zd64.js +0 -4
  774. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  775. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  776. package/dist/chunks/tree-h19v1jfz.js +0 -4
  777. package/dist/chunks/tsMode-2frah6h1.js +0 -14
  778. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  779. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
  780. package/src/panels/frontmatter-panel.ts +0 -701
  781. package/src/panels/git-panel.ts +0 -1120
  782. package/src/surfaces/doc-header.json +0 -776
  783. package/src/surfaces/doc-header.ts +0 -231
  784. package/src/surfaces/git-panel.json +0 -1880
  785. package/src/surfaces/git-panel.ts +0 -272
@@ -10,7 +10,7 @@
10
10
 
11
11
  import { createToolDefinition } from "@jxsuite/ai/tools";
12
12
  import type { ToolRegistry, ToolResult, WriteLedger } from "@jxsuite/ai/tools";
13
- import type { JxMutableNode, JxPath, JxStateDefinition } from "@jxsuite/schema/types";
13
+ import type { JsonObject, JxMutableNode, JxPath } from "@jxsuite/schema/types";
14
14
  import { getNodeAtPath } from "../state";
15
15
  import type { Tab } from "../tabs/tab";
16
16
  import {
@@ -32,7 +32,7 @@ import {
32
32
  snapshotBeforeWrite,
33
33
  translateValidationError,
34
34
  } from "./ai-write-report";
35
- import type { RenderVerdict } from "./ai-write-report";
35
+ import type { CandidateDocument, RenderVerdict } from "./ai-write-report";
36
36
 
37
37
  /* Re-exported from its new home so `ai-project-tools.ts` and the tests keep their import: the
38
38
  translation moved with the verdict it belongs to (`ai-write-report.ts`), where every document
@@ -43,6 +43,14 @@ const PATH_DESCRIPTION =
43
43
  "Path to a node in the document, as a JSON array of keys/indices from the root " +
44
44
  '(e.g. ["children", 0, "children", 1]). Use read_document to discover valid paths.';
45
45
 
46
+ /**
47
+ * The node at `path`, typed as what {@link getNodeAtPath} actually answers: a path the model made up
48
+ * runs off the tree, and that is `undefined`, which every tool here reports as "No node exists".
49
+ */
50
+ function nodeAt(doc: JxMutableNode, path: JxPath): JxMutableNode | undefined {
51
+ return getNodeAtPath(doc, path);
52
+ }
53
+
46
54
  /** Steering error for document tools called with no active tab. */
47
55
  function noDocError(): ToolResult {
48
56
  return {
@@ -64,8 +72,8 @@ function noDocError(): ToolResult {
64
72
  * @param {import("../tabs/tab").Tab} tab
65
73
  * @param {(t: import("../tabs/tab").Tab) => void} mutationFn
66
74
  * @param {string} summary
67
- * @param {(doc: unknown) => Promise<string[]>} validate
68
- * @param {((doc: unknown) => Promise<RenderVerdict>) | undefined} renderCheck
75
+ * @param {(doc: CandidateDocument) => Promise<string[]>} validate
76
+ * @param {((doc: CandidateDocument) => Promise<RenderVerdict>) | undefined} renderCheck
69
77
  * @param {Record<string, string> | undefined} projectStyle
70
78
  * @returns {Promise<import("@jxsuite/ai/tools").ToolResult>}
71
79
  */
@@ -74,8 +82,8 @@ async function applyAndValidate(
74
82
  tab: Tab,
75
83
  mutationFn: (t: Tab) => void,
76
84
  summary: string,
77
- validate: (doc: unknown) => Promise<string[]>,
78
- renderCheck: ((doc: unknown) => Promise<RenderVerdict>) | undefined,
85
+ validate: (doc: CandidateDocument) => Promise<string[]>,
86
+ renderCheck: ((doc: CandidateDocument) => Promise<RenderVerdict>) | undefined,
79
87
  projectStyle: Record<string, string> | undefined,
80
88
  ): Promise<ToolResult> {
81
89
  const deps = { getProjectStyle: () => projectStyle, renderCheck, validate };
@@ -109,9 +117,9 @@ async function applyAndValidate(
109
117
  * @param {import("@jxsuite/ai/tools").ToolRegistry} registry
110
118
  * @param {{
111
119
  * getTab: () => import("../tabs/tab").Tab | null;
112
- * validate?: (doc: unknown) => Promise<string[]>;
120
+ * validate?: (doc: CandidateDocument) => Promise<string[]>;
113
121
  * saveFile?: (relPath: string, content: string) => Promise<void>;
114
- * renderCheck?: (doc: unknown) => Promise<{ ok: true } | { ok: false; error: string }>;
122
+ * renderCheck?: (doc: CandidateDocument) => Promise<{ ok: true } | { ok: false; error: string }>;
115
123
  * projectStyle?: Record<string, string>;
116
124
  * getProjectStyle?: () => Record<string, string> | undefined;
117
125
  * findOpenTab?: (path: string) => import("../tabs/tab").Tab | null;
@@ -131,9 +139,9 @@ export function registerAiTools(
131
139
  reloadTab,
132
140
  }: {
133
141
  getTab: () => Tab | null;
134
- validate?: (doc: unknown) => Promise<string[]>;
142
+ validate?: (doc: CandidateDocument) => Promise<string[]>;
135
143
  saveFile?: (relPath: string, content: string) => Promise<void>;
136
- renderCheck?: (doc: unknown) => Promise<{ ok: true } | { ok: false; error: string }>;
144
+ renderCheck?: (doc: CandidateDocument) => Promise<{ ok: true } | { ok: false; error: string }>;
137
145
  projectStyle?: Record<string, string> | undefined;
138
146
  /**
139
147
  * Live variant of `projectStyle` — takes precedence; re-read per tool call so a project
@@ -195,9 +203,11 @@ export function registerAiTools(
195
203
  if (!tab) {
196
204
  return noDocError();
197
205
  }
206
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed, which refuses
207
+ a `path` that is present but not an array. Its items are not checked; a key that does
208
+ not resolve makes `nodeAt` answer undefined, reported just below. */
198
209
  const { path } = args as { path?: JxPath };
199
- const node =
200
- path && path.length > 0 ? getNodeAtPath(tab.doc.document, path) : tab.doc.document;
210
+ const node = path && path.length > 0 ? nodeAt(tab.doc.document, path) : tab.doc.document;
201
211
  if (node === undefined) {
202
212
  return { success: false, error: `No node exists at path ${JSON.stringify(path)}.` };
203
213
  }
@@ -239,8 +249,12 @@ export function registerAiTools(
239
249
  if (!tab) {
240
250
  return noDocError();
241
251
  }
252
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed: `path` is a
253
+ present array and `key` a present string. `value` declares no type, so it is any JSON
254
+ value or absent, all of which `JxNodeValue` includes. A `path` whose items do not resolve
255
+ is caught by `nodeAt` just below. */
242
256
  const { path, key, value } = args as { path: JxPath; key: string; value?: JxNodeValue };
243
- const node = getNodeAtPath(tab.doc.document, path);
257
+ const node = nodeAt(tab.doc.document, path);
244
258
  if (node === undefined) {
245
259
  return { success: false, error: `No node exists at path ${JSON.stringify(path)}.` };
246
260
  }
@@ -286,6 +300,11 @@ export function registerAiTools(
286
300
  if (!tab) {
287
301
  return noDocError();
288
302
  }
303
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed: `parentPath` is
304
+ a present array, `node` a present object, and `index` a present number — or a numeric
305
+ string, which the validator also admits for an integer and `splice` coerces alike.
306
+ `node` is a model-written tree whose shape the schema check after the write judges, and
307
+ a `parentPath` that does not resolve is caught just below. */
289
308
  const {
290
309
  parentPath,
291
310
  index,
@@ -295,7 +314,7 @@ export function registerAiTools(
295
314
  index: number;
296
315
  node: JxMutableNode;
297
316
  };
298
- const parent = getNodeAtPath(tab.doc.document, parentPath);
317
+ const parent = nodeAt(tab.doc.document, parentPath);
299
318
  if (parent === undefined) {
300
319
  return { success: false, error: `No node exists at path ${JSON.stringify(parentPath)}.` };
301
320
  }
@@ -373,12 +392,12 @@ export function registerAiTools(
373
392
  if (!tab) {
374
393
  return noDocError();
375
394
  }
376
- const { path, property, value } = args as {
377
- path: JxPath;
378
- property: string;
379
- value?: unknown;
380
- };
381
- if (getNodeAtPath(tab.doc.document, path) === undefined) {
395
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed: `path` is a
396
+ present array and `property` a present string; a `path` that does not resolve is caught
397
+ just below. `value` is read untyped and stringified. */
398
+ const { path, property } = args as { path: JxPath; property: string };
399
+ const { value } = args;
400
+ if (nodeAt(tab.doc.document, path) === undefined) {
382
401
  return { success: false, error: `No node exists at path ${JSON.stringify(path)}.` };
383
402
  }
384
403
  const prop = property;
@@ -420,8 +439,11 @@ export function registerAiTools(
420
439
  if (!tab) {
421
440
  return noDocError();
422
441
  }
442
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed: `path` is a
443
+ present array and `value` a present string; a `path` that does not resolve is caught
444
+ just below. */
423
445
  const { path, value } = args as { path: JxPath; value: string };
424
- if (getNodeAtPath(tab.doc.document, path) === undefined) {
446
+ if (nodeAt(tab.doc.document, path) === undefined) {
425
447
  return { success: false, error: `No node exists at path ${JSON.stringify(path)}.` };
426
448
  }
427
449
  return applyAndValidate(
@@ -469,7 +491,10 @@ export function registerAiTools(
469
491
  if (!tab) {
470
492
  return noDocError();
471
493
  }
472
- const { key, value } = args as { key: string; value: JxStateDefinition };
494
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed, so `key` is a
495
+ present string. */
496
+ const { key } = args as { key: string };
497
+ const { value } = args;
473
498
  if (tab.doc.document.state && tab.doc.document.state[key] !== undefined) {
474
499
  return {
475
500
  success: false,
@@ -482,6 +507,10 @@ export function registerAiTools(
482
507
  /* `mutateAddDef` rather than `mutateUpdateProperty`: the latter deletes on "", which is
483
508
  wrong for a state default (`"title": ""`). It also records the op, so the canvas, the
484
509
  history and collaborators each get the edit as an edit. */
510
+ /* SAFETY: `value` is required, so the registry refused it missing or null; it is the
511
+ model's state entry, possibly a scalar default (`0`, `""`) the schema admits.
512
+ `mutateAddDef` only clones `def` and stores it under `state[key]`, never reading it
513
+ as the object its parameter names. */
485
514
  (t) => mutateAddDef(t, key, value as Record<string, JsonValue>),
486
515
  `Added state "${key}".`,
487
516
  validate,
@@ -519,7 +548,10 @@ export function registerAiTools(
519
548
  if (!tab) {
520
549
  return noDocError();
521
550
  }
522
- const { key, value } = args as { key: string; value?: JxStateDefinition | null };
551
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed, so `key` is a
552
+ present string. */
553
+ const { key } = args as { key: string };
554
+ const { value } = args;
523
555
  if (!tab.doc.document.state || tab.doc.document.state[key] === undefined) {
524
556
  return {
525
557
  success: false,
@@ -535,6 +567,9 @@ export function registerAiTools(
535
567
  if (value == null) {
536
568
  mutateRemoveDef(t, key);
537
569
  } else {
570
+ /* SAFETY: the model's state entry, possibly a scalar default the schema admits.
571
+ `mutateAddDef` only clones `def` and stores it under `state[key]`, never reading
572
+ it as the object its parameter names. */
538
573
  mutateAddDef(t, key, value as Record<string, JsonValue>);
539
574
  }
540
575
  },
@@ -580,6 +615,9 @@ export function registerAiTools(
580
615
  if (!tab) {
581
616
  return noDocError();
582
617
  }
618
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed: both paths are
619
+ present arrays, and `toIndex` a present number or numeric string (the validator admits
620
+ both for an integer). Paths that do not resolve are caught just below. */
583
621
  const { fromPath, toParentPath, toIndex } = args as {
584
622
  fromPath: JxPath;
585
623
  toParentPath: JxPath;
@@ -588,13 +626,13 @@ export function registerAiTools(
588
626
  if (fromPath.length < 2) {
589
627
  return { success: false, error: "Cannot move the document root." };
590
628
  }
591
- if (getNodeAtPath(tab.doc.document, fromPath) === undefined) {
629
+ if (nodeAt(tab.doc.document, fromPath) === undefined) {
592
630
  return {
593
631
  success: false,
594
632
  error: `No node exists at fromPath ${JSON.stringify(fromPath)}.`,
595
633
  };
596
634
  }
597
- if (getNodeAtPath(tab.doc.document, toParentPath) === undefined) {
635
+ if (nodeAt(tab.doc.document, toParentPath) === undefined) {
598
636
  return {
599
637
  success: false,
600
638
  error: `No node exists at toParentPath ${JSON.stringify(toParentPath)}.`,
@@ -644,7 +682,10 @@ export function registerAiTools(
644
682
  error: "File operations are not available in this environment.",
645
683
  };
646
684
  }
647
- const { path, content } = args as { path: string; content: object };
685
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed: `path` is a
686
+ present string and `content` a present JSON object (not an array, not null). Whether that
687
+ object is a Jx document is what `validate` and `renderCheck` below decide. */
688
+ const { path, content } = args as { path: string; content: JsonObject };
648
689
  // Inside the project or not at all (ai.md §4): the platform write is given this path.
649
690
  const relPath = normalizeRelPath(path);
650
691
  if (relPath === null) {
@@ -728,7 +769,10 @@ export function registerAiTools(
728
769
  error: "File operations are not available in this environment.",
729
770
  };
730
771
  }
731
- const { path, content } = args as { path: string; content: object };
772
+ /* SAFETY: a strict tool runs only after the registry's `validate()` passed: `path` is a
773
+ present string and `content` a present JSON object (not an array, not null). Whether that
774
+ object is a Jx document is what `validate` and `renderCheck` below decide. */
775
+ const { path, content } = args as { path: string; content: JsonObject };
732
776
  const relPath = normalizeRelPath(path);
733
777
  if (relPath === null) {
734
778
  return invalidPathResult(path);
@@ -2,26 +2,27 @@
2
2
  * Ai-write-report.ts — what the model is told after a document write, whoever made it.
3
3
  *
4
4
  * Extracted from `ai-tools.ts`'s `applyAndValidate`, which used to own both halves of a document
5
- * tool: the transaction and the verdict on it. The verdict is the half every document write needs
6
- * — the seven hand-registered tree tools AND every command the assistant runs through
5
+ * tool: the transaction and the verdict on it. The verdict is the half every document write needs —
6
+ * the seven hand-registered tree tools AND every command the assistant runs through
7
7
  * `services/ai-command-tools.ts` — so it lives here, in two functions the caller brackets its write
8
8
  * with:
9
9
  *
10
- * 1. {@link snapshotBeforeWrite} reads the document's schema errors and render state BEFORE the
11
- * write, because the loop's signal (specs/ai.md §3.1) is "what did this edit newly introduce",
12
- * not "is the document valid": a page that was already broken must not make every subsequent
13
- * edit read as the culprit.
10
+ * 1. {@link snapshotBeforeWrite} reads the document's schema errors and render state BEFORE the write,
11
+ * because the loop's signal (specs/ai.md §3.1) is "what did this edit newly introduce", not "is
12
+ * the document valid": a page that was already broken must not make every subsequent edit read
13
+ * as the culprit.
14
14
  * 2. {@link reportDocumentWrite} compares AFTER the write, translating each new schema error into a
15
- * fix hint the model can act on, running the render check only when rendering worked before,
16
- * and appending the soft token-discipline hints to a success.
15
+ * fix hint the model can act on, running the render check only when rendering worked before, and
16
+ * appending the soft token-discipline hints to a success.
17
17
  *
18
- * The change stays applied either way (optimistic apply + undo, specs/ai.md §3.1); reporting the errors lets
19
- * the agent loop self-correct on the next round.
18
+ * The change stays applied either way (optimistic apply + undo, specs/ai.md §3.1); reporting the
19
+ * errors lets the agent loop self-correct on the next round.
20
20
  *
21
21
  * @license MIT
22
22
  */
23
23
 
24
24
  import type { ToolResult } from "@jxsuite/ai/tools";
25
+ import type { JsonValue, JxMutableNode } from "@jxsuite/schema/types";
25
26
  import { toRaw } from "../reactivity";
26
27
  import type { Tab } from "../tabs/tab";
27
28
  import { flagHardcodedTokens, formatTokenHints } from "./token-lint";
@@ -29,12 +30,19 @@ import { flagHardcodedTokens, formatTokenHints } from "./token-lint";
29
30
  /** A render probe's answer: rendered, or the message it threw. */
30
31
  export type RenderVerdict = { ok: true } | { ok: false; error: string };
31
32
 
33
+ /**
34
+ * A document as the validator and the render probe receive it: the live tree of an open tab, or the
35
+ * JSON a tool was handed (a `create_page` argument, a parsed `write_file` body) before anything has
36
+ * said it is a document. Judging that is what the two of them are for.
37
+ */
38
+ export type CandidateDocument = JxMutableNode | JsonValue;
39
+
32
40
  /** What a write reporter needs. Every member is what `registerAiTools` already takes by injection. */
33
41
  export interface WriteReportDeps {
34
42
  /** Schema errors for a document, as raw ajv sentences. */
35
- validate: (doc: unknown) => Promise<string[]>;
43
+ validate: (doc: CandidateDocument) => Promise<string[]>;
36
44
  /** The detached-DOM render probe, when the host has one. */
37
- renderCheck?: ((doc: unknown) => Promise<RenderVerdict>) | undefined;
45
+ renderCheck?: ((doc: CandidateDocument) => Promise<RenderVerdict>) | undefined;
38
46
  /** The project's design tokens, read per call so a project opened mid-session contributes. */
39
47
  getProjectStyle?: (() => Record<string, string> | undefined) | undefined;
40
48
  }
@@ -22,7 +22,7 @@
22
22
  * @docs studio/ai/chat
23
23
  */
24
24
 
25
- import type { Message } from "@jxsuite/ai/chat-state";
25
+ import type { LiveMessage } from "@jxsuite/ai/messages";
26
26
  import { createLedger } from "@jxsuite/ai/tools";
27
27
  import type { AiWrite, WriteLedger } from "@jxsuite/ai/tools";
28
28
 
@@ -113,7 +113,7 @@ export function summarizeWrites(writes: AiWrite[]): string {
113
113
  return failed > 0 ? `${failed} change${failed === 1 ? "" : "s"} failed` : "";
114
114
  }
115
115
  const files = `Changed ${paths.size} file${paths.size === 1 ? "" : "s"}`;
116
- const diskPaths = new Set(applied.filter((w) => w.disk).map((w) => w.path));
116
+ const diskPaths = new Set(applied.flatMap((w) => (w.disk ? [w.path] : [])));
117
117
  const parts = [files];
118
118
  if (diskPaths.size > 0) {
119
119
  parts.push(
@@ -150,13 +150,13 @@ export function resetAiWrites(): void {
150
150
  * message in it belongs to some other conversation: filing there would draw "Changed 1 file", and
151
151
  * Restore, under a reply that changed nothing.
152
152
  *
153
- * @param {readonly Message[]} messages
153
+ * @param {readonly LiveMessage[]} messages
154
154
  * @param {string} [userId] - The id of the user message this turn answers; without one, the whole
155
155
  * transcript is the turn
156
156
  * @returns {string | null} Null when the turn drew nothing (so it ran no tool either), or when its
157
157
  * user message has left the transcript
158
158
  */
159
- export function turnAnchor(messages: readonly Message[], userId?: string): string | null {
159
+ export function turnAnchor(messages: readonly LiveMessage[], userId?: string): string | null {
160
160
  let anchor: string | null = null;
161
161
  for (let index = messages.length - 1; index >= 0; index--) {
162
162
  const message = messages[index]!;
@@ -37,10 +37,12 @@ import { seedProjectList } from "../project-list";
37
37
  import { activeTab } from "../workspace/workspace";
38
38
  import { shell } from "../shell";
39
39
  import { collabState } from "../collab/collab-state";
40
+ import { isNonNullObject, isString } from "@jxsuite/schema/guards";
40
41
  import { canvasPointAt, revealCanvasPath } from "../canvas/iframe-host";
41
42
  import { probeIdle } from "./idle";
42
43
  import type { CanvasPoint } from "../canvas/iframe-host";
43
44
  import type { IdleOptions } from "./idle";
45
+ import type { CommandArgValues } from "../commands/command-args";
44
46
  import type { CommandContext } from "../commands/context";
45
47
  import type { AnyCommand, CommandRegistry } from "../commands/registry";
46
48
  import type { PeerPresence } from "../collab/collab-state";
@@ -50,9 +52,6 @@ import type { GitBranchesResult, GitStatusResult, ProjectListEntry } from "../ty
50
52
  import type { GitLogEntry } from "../shell";
51
53
  import type { JxPath } from "../state";
52
54
 
53
- /** Loosely-typed arguments, as they arrive from a manifest step, a palette prompt or a tool call. */
54
- export type AutomationArgs = Record<string, unknown>;
55
-
56
55
  /**
57
56
  * What the hook needs that it cannot import.
58
57
  *
@@ -93,13 +92,14 @@ export function isScriptable(command: AnyCommand): boolean {
93
92
  // ─── The registry-gap declaration ─────────────────────────────────────────────
94
93
 
95
94
  /**
96
- * How a manifest id the registry does not declare is going to stop existing.
95
+ * Why a manifest id the registry does not declare will never be one.
97
96
  *
98
- * - `command` — a thing a user does, so it becomes a registry record. The value names who lands it.
99
- * - `seed` — a remote's state, addressed through {@link AutomationApi.seed}.
100
- * - `refused` — §13.5 says the app will never provide it; the manifest step is deleted.
97
+ * There were three fates. `command` (a thing a user does, so it becomes a registry record) emptied
98
+ * when `media.browse` landed in `media/media-commands.ts`, the last of them; `seed` (a remote's
99
+ * state) is answered from {@link seedIds}. What is left is `refused`: §13.5 says the app will never
100
+ * provide it, and the manifest step is deleted.
101
101
  */
102
- export type GapDisposition = "command" | "seed" | "refused";
102
+ export type GapDisposition = "refused";
103
103
 
104
104
  export interface ManifestId {
105
105
  disposition: GapDisposition;
@@ -118,19 +118,18 @@ export interface ManifestId {
118
118
  * — only to explain, when the registry refuses an id, which of the three fates that id has.
119
119
  *
120
120
  * This is a countdown, in the idiom of the checker's own `TOGGLE_DEBT`: it may only shrink. It went
121
- * 39 → 8 when the manifest converted, and 8 → 7 when `element.insertData` became `insert.data`
122
- * (`canvas/canvas-render.ts`). What left: every `seed` entry, now read off {@link seedIds} and
121
+ * 39 → 8 when the manifest converted, 8 → 7 when `element.insertData` became `insert.data`
122
+ * (`canvas/canvas-render.ts`), and down to five when `media.browse` became a record of its own
123
+ * (`media/media-commands.ts`). What left: every `seed` entry, now read off {@link seedIds} and
123
124
  * answered from the live registry rather than from a hand-kept list; every `toggle*` entry, which
124
- * {@link TOGGLE_ID} refuses before this map is ever consulted; and every `command` entry whose
125
- * record has since landed.
125
+ * {@link TOGGLE_ID} refuses before this map is ever consulted; and every `command` entry, each of
126
+ * whose records has landed.
126
127
  *
127
- * What is left is two kinds. Two `command` entries are the manifest's real registry gaps — each
128
- * reached today by an `input` step clicking a hand-stamped region, and each of those steps carries
129
- * an `unstable` hatch naming the phase that lands the record, so this map and that hatch count are
130
- * the same debt. Five `refused` entries are NOT a countdown: they are §13.5's normative refusals,
131
- * and they stay so that a caller reaching for one gets the reason instead of "unknown command".
128
+ * What is left is one kind, and it is NOT a countdown: five `refused` entries, §13.5's normative
129
+ * refusals, which stay so that a caller reaching for one gets the reason instead of "unknown
130
+ * command".
132
131
  */
133
- export const AUTOMATION_COMMANDS: Readonly<Record<string, ManifestId>> = {
132
+ export const AUTOMATION_COMMANDS = {
134
133
  "file.contextMenu": {
135
134
  disposition: "refused",
136
135
  note: "opening a menu to press an item names a control; the ITEM is the command",
@@ -139,20 +138,25 @@ export const AUTOMATION_COMMANDS: Readonly<Record<string, ManifestId>> = {
139
138
  disposition: "refused",
140
139
  note: "matched RENDERED TEXT, which R1 of scripts/screenshots/README.md forbids; a row is addressed by its data-jx-path",
141
140
  },
142
- "media.browse": { disposition: "command", note: "media.browse, site-architecture.md §9.4" },
143
141
  "project.showWelcome": {
144
142
  disposition: "refused",
145
143
  note: "cold start is a startup profile (?profile=fresh), not an action",
146
144
  },
147
145
  "settings.setSection": {
148
146
  disposition: "refused",
149
- note: 'mirrored the section registry\'s LABELS; say settings.open { section: "cssVars" }',
147
+ note: 'mirrored the section registry\'s LABELS; say settings.open { section: "contexts" }',
150
148
  },
151
149
  "view.setStatus": {
152
150
  disposition: "refused",
153
151
  note: "the status bar is not staged — if a capture needs a calm shell, the app must BE calm",
154
152
  },
155
- };
153
+ } as const satisfies Readonly<Record<string, ManifestId>>;
154
+
155
+ /**
156
+ * {@link AUTOMATION_COMMANDS} keyed for lookup by an arbitrary id. A Map rather than an index into
157
+ * the object, so an id such as `"constructor"` finds nothing instead of `Object.prototype`'s.
158
+ */
159
+ const COMMAND_GAPS: ReadonlyMap<string, ManifestId> = new Map(Object.entries(AUTOMATION_COMMANDS));
156
160
 
157
161
  // ─── The seed registry, under the Remote Rule ─────────────────────────────────
158
162
 
@@ -161,7 +165,7 @@ export interface SeedDefinition {
161
165
  id: string;
162
166
  /** The network or IPC boundary this seed stands in for. The Remote Rule, written down per seed. */
163
167
  boundary: string;
164
- run: (args: AutomationArgs) => void | Promise<void>;
168
+ run: (args: CommandArgValues) => void | Promise<void>;
165
169
  }
166
170
 
167
171
  /**
@@ -170,7 +174,7 @@ export interface SeedDefinition {
170
174
  * Every one of these was a method on the old surface. Each writes state a USER writes, so each is a
171
175
  * COMMAND — and a fixture that stages it photographs a state no session could have reached.
172
176
  */
173
- export const REFUSED_SEEDS: Readonly<Record<string, string>> = {
177
+ export const REFUSED_SEEDS = {
174
178
  openSettings: 'a user opens Settings — run("settings.open")',
175
179
  select: 'a user selects a node — run("selection.set", { path })',
176
180
  setActivity: 'a user picks a Navigator panel — run("navigator.showPanel", { panel })',
@@ -178,9 +182,12 @@ export const REFUSED_SEEDS: Readonly<Record<string, string>> = {
178
182
  setStatus:
179
183
  "the status bar reports what the app just did; staging it is the one lie the Remote Rule (studio.md §13.5) names outright",
180
184
  setZoom: 'a user zooms — run("canvas.setZoom", { zoom })',
181
- };
185
+ } as const satisfies Readonly<Record<string, string>>;
186
+
187
+ /** {@link REFUSED_SEEDS} keyed for lookup by an arbitrary seed name, as {@link COMMAND_GAPS} is. */
188
+ const SEED_REFUSALS: ReadonlyMap<string, string> = new Map(Object.entries(REFUSED_SEEDS));
182
189
 
183
- function arrayArg<T>(args: AutomationArgs, key: string): T[] {
190
+ function arrayArg<T>(args: CommandArgValues, key: string): T[] {
184
191
  const value = args[key];
185
192
  if (value === undefined) {
186
193
  return [];
@@ -188,23 +195,28 @@ function arrayArg<T>(args: AutomationArgs, key: string): T[] {
188
195
  if (!Array.isArray(value)) {
189
196
  throw new TypeError(`seed argument "${key}" must be an array`);
190
197
  }
198
+ /* SAFETY: a seed's arguments are a fixture written against the boundary type it stands in for
199
+ (the screenshot manifest's `seed` steps), so only the container is checked here — exactly as
200
+ much as the remote it replaces would have checked before handing its JSON over. */
191
201
  return value as T[];
192
202
  }
193
203
 
194
- function requiredArg<T>(args: AutomationArgs, key: string): T {
204
+ function requiredArg<T>(args: CommandArgValues, key: string): T {
195
205
  const value = args[key];
196
- if (value === null || typeof value !== "object") {
206
+ if (!isNonNullObject(value)) {
197
207
  throw new TypeError(`seed argument "${key}" must be an object`);
198
208
  }
209
+ /* SAFETY: as in `arrayArg`: a fixture written against the boundary type it stands in for, of
210
+ which only the object container is checked here. */
199
211
  return value as T;
200
212
  }
201
213
 
202
- function optionalString(args: AutomationArgs, key: string): string | undefined {
214
+ function optionalString(args: CommandArgValues, key: string): string | undefined {
203
215
  const value = args[key];
204
216
  if (value === undefined) {
205
217
  return undefined;
206
218
  }
207
- if (typeof value !== "string") {
219
+ if (!isString(value)) {
208
220
  throw new TypeError(`seed argument "${key}" must be a string`);
209
221
  }
210
222
  return value;
@@ -216,7 +228,9 @@ function optionalString(args: AutomationArgs, key: string): string | undefined {
216
228
  * Each one writes exactly what its named boundary would have written, and nothing else — the git
217
229
  * seed does not also open the Source Control panel, because a user does that.
218
230
  */
219
- export function createSeeds(deps: AutomationDeps): SeedDefinition[] {
231
+ export function createSeeds(
232
+ deps: Pick<AutomationDeps, "seedAssistantMessages" | "seedPublishConnected">,
233
+ ): SeedDefinition[] {
220
234
  return [
221
235
  {
222
236
  boundary: "the assistant's model stream",
@@ -252,10 +266,13 @@ export function createSeeds(deps: AutomationDeps): SeedDefinition[] {
252
266
  id: "seed.publish",
253
267
  run: (args) => {
254
268
  const accountId = optionalString(args, "accountId");
255
- deps.seedPublishConnected({
269
+ const connected: Parameters<AutomationDeps["seedPublishConnected"]>[0] = {
256
270
  deployment: requiredArg<PagesDeploymentInfo>(args, "deployment"),
257
- ...(accountId ? { accountId } : {}),
258
- });
271
+ };
272
+ if (accountId) {
273
+ connected.accountId = accountId;
274
+ }
275
+ deps.seedPublishConnected(connected);
259
276
  },
260
277
  },
261
278
  {
@@ -264,9 +281,16 @@ export function createSeeds(deps: AutomationDeps): SeedDefinition[] {
264
281
  run: (args) => {
265
282
  // The working tree really is a remote here: the git-panel shot photographs whatever the
266
283
  // Author happened to have dirty, because its project lives inside this repository.
267
- shell.git.status = (args.status as GitStatusResult | undefined) ?? null;
268
- shell.git.branches = (args.branches as GitBranchesResult | undefined) ?? null;
269
- shell.git.logEntries = (args.log as GitLogEntry[] | undefined) ?? null;
284
+ /* SAFETY: as in `arrayArg`: a fixture written against the platform's git route answers it
285
+ stands in for, passed on as the route's JSON would have been, unchecked. */
286
+ const { status, branches, log } = args as {
287
+ status?: GitStatusResult;
288
+ branches?: GitBranchesResult;
289
+ log?: GitLogEntry[];
290
+ };
291
+ shell.git.status = status ?? null;
292
+ shell.git.branches = branches ?? null;
293
+ shell.git.logEntries = log ?? null;
270
294
  shell.git.loading = false;
271
295
  shell.git.error = null;
272
296
  render();
@@ -293,12 +317,9 @@ export function createSeeds(deps: AutomationDeps): SeedDefinition[] {
293
317
  * its `run`, never while building it, so the no-op deps below can never be called.
294
318
  */
295
319
  export function seedIds(): string[] {
296
- const inert = {
297
- registry: undefined as unknown as CommandRegistry,
298
- seedAssistantMessages: () => {},
299
- seedPublishConnected: () => {},
300
- } satisfies AutomationDeps;
301
- return createSeeds(inert).map((seed) => seed.id);
320
+ return createSeeds({ seedAssistantMessages: () => {}, seedPublishConnected: () => {} }).map(
321
+ (seed) => seed.id,
322
+ );
302
323
  }
303
324
 
304
325
  // ─── The API ──────────────────────────────────────────────────────────────────
@@ -340,8 +361,8 @@ export interface AutomationProbe {
340
361
  }
341
362
 
342
363
  export interface AutomationApi {
343
- run: (id: string, args?: AutomationArgs) => Promise<void>;
344
- seed: (id: string, args?: AutomationArgs) => Promise<void>;
364
+ run: (id: string, args?: CommandArgValues) => Promise<void>;
365
+ seed: (id: string, args?: CommandArgValues) => Promise<void>;
345
366
  probe: AutomationProbe;
346
367
  }
347
368
 
@@ -391,12 +412,9 @@ function unknownCommandMessage(
391
412
  if (seeds.has(id)) {
392
413
  return `"${id}" is a seed, not a command — call seed("${id}", …)`;
393
414
  }
394
- const gap = AUTOMATION_COMMANDS[id];
395
- if (gap?.disposition === "refused") {
396
- return `"${id}" is refused by spec §13.5: ${gap.note}`;
397
- }
415
+ const gap = COMMAND_GAPS.get(id);
398
416
  if (gap) {
399
- return `"${id}" has no command record yet (${gap.note}) — __jxAutomation.run projects the registry and nothing else`;
417
+ return `"${id}" is refused by spec §13.5: ${gap.note}`;
400
418
  }
401
419
  const known = registry
402
420
  .list()
@@ -435,7 +453,7 @@ export function createAutomationApi(deps: AutomationDeps): AutomationApi {
435
453
  },
436
454
  async seed(id, args = {}) {
437
455
  const bare = id.startsWith("seed.") ? id.slice(5) : id;
438
- const refusal = REFUSED_SEEDS[bare];
456
+ const refusal = SEED_REFUSALS.get(bare);
439
457
  if (refusal) {
440
458
  throw new AutomationRefusedError(
441
459
  id,
@@ -453,6 +471,11 @@ export function createAutomationApi(deps: AutomationDeps): AutomationApi {
453
471
  };
454
472
  }
455
473
 
474
+ declare global {
475
+ /** The automation hook, installed only on a page load that opted in with `?automation=1`. */
476
+ var __jxAutomation: AutomationApi | undefined;
477
+ }
478
+
456
479
  /** The hook is opt-in per page load: only `?automation=1` installs it. */
457
480
  export function shouldInstallAutomation(search: string): boolean {
458
481
  return new URLSearchParams(search).get("automation") === "1";
@@ -466,6 +489,6 @@ export function installAutomationHook(deps: AutomationDeps): boolean {
466
489
  if (!shouldInstallAutomation(location.search)) {
467
490
  return false;
468
491
  }
469
- (globalThis as Record<string, unknown>).__jxAutomation = createAutomationApi(deps);
492
+ globalThis.__jxAutomation = createAutomationApi(deps);
470
493
  return true;
471
494
  }