@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
@@ -23,6 +23,7 @@
23
23
 
24
24
  import { activeTab } from "../workspace/workspace";
25
25
  import { clearProblems, notify, problemFindings } from "./notify";
26
+ import type { NotifyOptions } from "./notify";
26
27
  import {
27
28
  findPopoverDefects,
28
29
  popoverDisplayRepair,
@@ -39,7 +40,8 @@ import {
39
40
  } from "../tabs/transact";
40
41
  import { getNodeAtPath } from "../state";
41
42
  import type { AnyCommand, CommandRegistry } from "../commands/registry";
42
- import type { JxElement, JxMutableNode } from "@jxsuite/schema/types";
43
+ import type { CommandArgValues } from "../commands/command-args";
44
+ import type { JxElement } from "@jxsuite/schema/types";
43
45
  import type { JxPath } from "../state";
44
46
  import type { PopoverFix, PopoverPath } from "@jxsuite/schema/overlays";
45
47
 
@@ -100,7 +102,7 @@ export function reportPopoverProblems(doc: JxElement, path?: string): number {
100
102
  const defects = findPopoverDefects(doc, KIT_SCOPE);
101
103
  for (const defect of defects) {
102
104
  const action = defect.fix === undefined ? undefined : REPAIR_COMMAND[defect.fix];
103
- notify(defect.severity, defect.message, {
105
+ const options: NotifyOptions = {
104
106
  detail: defect.detail,
105
107
  /* Keyed by RULE AND PATH, not by rule alone: a header with two popovers can carry the same
106
108
  defect twice, and a key that collapsed them would report one and silently drop the other.
@@ -109,32 +111,45 @@ export function reportPopoverProblems(doc: JxElement, path?: string): number {
109
111
  key: problemKey(seen, "popover", defect.rule, defect.path),
110
112
  source: POPOVER_PROBLEM_SOURCE,
111
113
  tier: "problem",
112
- ...(action === undefined ? {} : { action, actionArgs: { path: defect.path } }),
113
- ...(path === undefined ? {} : { path }),
114
- });
114
+ };
115
+ if (action !== undefined) {
116
+ options.action = action;
117
+ options.actionArgs = { path: defect.path };
118
+ }
119
+ if (path !== undefined) {
120
+ options.path = path;
121
+ }
122
+ notify(defect.severity, defect.message, options);
115
123
  }
116
124
  /* The dialog and invoker-command rules (`spec.md` §8.7) file under the same source: one report
117
125
  for everything the platform overlays. They carry no repair button yet — the popover repairs
118
126
  move `display` into `:popover-open`, and a dialog's open rule is a different selector. */
119
127
  const dialogDefects = findDialogDefects(doc, KIT_SCOPE);
120
128
  for (const defect of dialogDefects) {
121
- notify(defect.severity, defect.message, {
129
+ const options: NotifyOptions = {
122
130
  detail: defect.detail,
123
131
  key: problemKey(seen, "dialog", defect.rule, defect.path),
124
132
  source: POPOVER_PROBLEM_SOURCE,
125
133
  tier: "problem",
126
- ...(path === undefined ? {} : { path }),
127
- });
134
+ };
135
+ if (path !== undefined) {
136
+ options.path = path;
137
+ }
138
+ notify(defect.severity, defect.message, options);
128
139
  }
129
140
  return defects.length + dialogDefects.length;
130
141
  }
131
142
 
132
143
  /** Read the path argument a repair command was invoked with, or throw naming the command. */
133
- function repairPath(id: string, args: Record<string, unknown> | undefined): JxPath {
144
+ function repairPath(id: string, args: CommandArgValues | undefined): JxPath {
134
145
  const path = args?.path;
135
146
  if (!Array.isArray(path)) {
136
147
  throw new RangeError(`command "${id}" needs a "path" argument naming the popover`);
137
148
  }
149
+ /* SAFETY: every repair record below declares `path` as an array whose items are
150
+ `["string", "number"]`, which `coerceArgs` reads as a path argument and checks segment by
151
+ segment (`pathArg`) before `run` is called — so an array that reached here holds only string
152
+ keys and numeric indexes. */
138
153
  return path as JxPath;
139
154
  }
140
155
 
@@ -217,7 +232,7 @@ export function popoverCommands(): AnyCommand[] {
217
232
  const id = "document.repairPopoverDisplay";
218
233
  const tab = repairTab(id);
219
234
  const path = repairPath(id, args);
220
- const node = getNodeAtPath(tab.doc.document, path) as JxMutableNode | undefined;
235
+ const node = getNodeAtPath(tab.doc.document, path);
221
236
  const repair = popoverDisplayRepair(node?.style);
222
237
  if (!repair) {
223
238
  throw new RangeError(`command "${id}": nothing to move — this popover sets no display`);
@@ -10,12 +10,15 @@
10
10
  */
11
11
 
12
12
  import { evaluateExpression, isMutating } from "@jxsuite/runtime/expression";
13
+ import { isNonNullObject } from "@jxsuite/schema/guards";
13
14
  import { toRaw } from "../reactivity";
14
15
  // Imported for local use AND re-exported below so existing consumers keep their import site.
15
16
  // oxlint-disable-next-line unicorn/prefer-export-from
16
17
  import { formatPreviewValue } from "../utils/preview-format";
18
+ import type { PreviewValue } from "../utils/preview-format";
17
19
 
18
- import type { ExpressionNode } from "@jxsuite/runtime/expression";
20
+ import type { JxScope } from "@jxsuite/runtime/types";
21
+ import type { JxExpressionNode, JxExpressionOperand } from "@jxsuite/schema/types";
19
22
 
20
23
  export interface ExpressionPreview {
21
24
  /** Path-keyed display values: "" is the root node, "value/target" a nested operand, etc. */
@@ -36,14 +39,14 @@ export { formatPreviewValue };
36
39
  * (canvas not yet rendered) — the editor renders no badges rather than wrong ones.
37
40
  */
38
41
  export function previewExpression(
39
- node: unknown,
40
- scope?: Record<string, unknown> | null,
42
+ node: JxExpressionOperand | undefined,
43
+ scope?: JxScope | null,
41
44
  ): ExpressionPreview | null {
42
- if (!scope || !node || typeof node !== "object" || !("operator" in node)) {
45
+ if (!scope || !isNonNullObject(node) || !("operator" in node)) {
43
46
  return null;
44
47
  }
45
48
 
46
- let state: Record<string, unknown>;
49
+ let state: JxScope;
47
50
  try {
48
51
  // Callers hand over tab.session.canvas.scope, which the reactive session tree wraps in a
49
52
  // Proxy — structuredClone rejects proxies, so unwrap to the raw snapshot first.
@@ -54,11 +57,20 @@ export function previewExpression(
54
57
  }
55
58
 
56
59
  const values = new Map<string, string>();
57
- const expr = node as ExpressionNode;
60
+ /* SAFETY: an operand object carrying `operator` is the expression-node member of the operand
61
+ union (the plain-object member is an options bag, which has no operator), and a node whose
62
+ other members are malformed throws inside `evaluateExpression`, which this preview reports
63
+ as its `error` rather than trusting. */
64
+ const expr = node as JxExpressionNode;
58
65
  let errorMessage: string | null = null;
59
66
  try {
60
- evaluateExpression(expr, state, null, undefined, {
61
- report: (path, value) => values.set(path.join("/"), formatPreviewValue(value)),
67
+ void evaluateExpression(expr, state, null, undefined, {
68
+ report: (path, value) => {
69
+ /* SAFETY: the trace reports raw runtime values, and PreviewValue names every category a JS
70
+ value falls in (primitive, bigint, symbol, function, array, record); formatting relies on
71
+ nothing beyond what JSON.stringify and String() accept for any value. */
72
+ values.set(path.join("/"), formatPreviewValue(value as PreviewValue));
73
+ },
62
74
  });
63
75
  } catch (error) {
64
76
  errorMessage = error instanceof Error ? error.message : String(error);
@@ -40,7 +40,7 @@ export interface StartupProfile {
40
40
  * `default` is not a no-op by omission — it is a named state, so "the app started normally" and
41
41
  * "the profile was unrecognised" are different outcomes and the second one is loud.
42
42
  */
43
- export const STARTUP_PROFILES: Readonly<Record<string, StartupProfile>> = {
43
+ export const STARTUP_PROFILES = {
44
44
  default: {
45
45
  description: "Resume whatever was persisted — layout, recents, settings, chat history.",
46
46
  id: "default",
@@ -51,7 +51,10 @@ export const STARTUP_PROFILES: Readonly<Record<string, StartupProfile>> = {
51
51
  id: "fresh",
52
52
  reset: "app-state",
53
53
  },
54
- };
54
+ } satisfies Readonly<Record<string, StartupProfile>>;
55
+
56
+ /** {@link STARTUP_PROFILES} by id, for a lookup whose id arrives from the query string. */
57
+ const PROFILES_BY_ID = new Map<string, StartupProfile>(Object.entries(STARTUP_PROFILES));
55
58
 
56
59
  export const DEFAULT_PROFILE_ID = "default";
57
60
 
@@ -77,7 +80,8 @@ export function isStudioStorageKey(key: string): boolean {
77
80
  * @returns The keys removed, so a caller (Preferences, a test) can report what it did.
78
81
  */
79
82
  export function clearStudioStorage(): string[] {
80
- const store = globalThis.localStorage as Storage | undefined;
83
+ // `localStorage` is absent outside a browser realm (Bun without a DOM shim), whatever lib.dom says.
84
+ const store = typeof localStorage === "undefined" ? undefined : localStorage;
81
85
  if (!store) {
82
86
  return [];
83
87
  }
@@ -105,10 +109,10 @@ export function clearStudioStorage(): string[] {
105
109
  * `default` would start the app in the state the caller was trying to avoid.
106
110
  */
107
111
  export function applyProfile(id: string): StartupProfile {
108
- const profile = STARTUP_PROFILES[id];
112
+ const profile = PROFILES_BY_ID.get(id);
109
113
  if (!profile) {
110
114
  throw new RangeError(
111
- `unknown startup profile "${id}"; declared: ${Object.keys(STARTUP_PROFILES).join(", ")}`,
115
+ `unknown startup profile "${id}"; declared: ${[...PROFILES_BY_ID.keys()].join(", ")}`,
112
116
  );
113
117
  }
114
118
  if (profile.reset === "app-state") {
@@ -137,7 +141,10 @@ export function applyStartupProfile(search?: string): StartupState {
137
141
  if (_startup) {
138
142
  return _startup;
139
143
  }
140
- const query = new URLSearchParams(search ?? globalThis.location?.search ?? "");
144
+ // `location` is absent outside a browser realm, which is why the tests pass `search` themselves.
145
+ const query = new URLSearchParams(
146
+ search ?? (typeof location === "undefined" ? "" : location.search),
147
+ );
141
148
  const profile = applyProfile(query.get("profile") ?? DEFAULT_PROFILE_ID);
142
149
  const clockParam = query.get("clock");
143
150
  _startup = { clock: clockParam === null ? null : pinClock(clockParam), profile };
@@ -2,15 +2,17 @@
2
2
  * Project-path.ts — the containment check the assistant's file tools run before they touch disk.
3
3
  *
4
4
  * `ai.md` §4: a file tool refuses a path outside the open project itself, rather than leaving the
5
- * server to. `list_files`, `read_file` and `write_file` always refused one; `create_component`
6
- * and `create_page` took the model's path as given and handed it to the platform write. One module,
7
- * so the two sets of tools cannot disagree about what "inside the project" means, and a leaf,
8
- * because the document tools and the project tools already import each other's neighbours.
5
+ * server to. `list_files`, `read_file` and `write_file` always refused one; `create_component` and
6
+ * `create_page` took the model's path as given and handed it to the platform write. One module, so
7
+ * the two sets of tools cannot disagree about what "inside the project" means, and a leaf, because
8
+ * the document tools and the project tools already import each other's neighbours.
9
9
  *
10
- * @docs studio/ai/chat
11
10
  * @license MIT
11
+ * @docs studio/ai/chat
12
12
  */
13
13
 
14
+ import { isString } from "@jxsuite/schema/guards";
15
+ import type { JsonValue } from "@jxsuite/schema/types";
14
16
  import type { ToolResult } from "@jxsuite/ai/tools";
15
17
 
16
18
  /**
@@ -18,11 +20,12 @@ import type { ToolResult } from "@jxsuite/ai/tools";
18
20
  * `..` segments, drive letters, a home directory). The server re-checks; this keeps the error
19
21
  * actionable.
20
22
  *
21
- * @param {unknown} path
23
+ * @param {JsonValue | undefined} path A tool argument as the model sent it — any JSON value, or
24
+ * absent.
22
25
  * @returns {string | null}
23
26
  */
24
- export function normalizeRelPath(path: unknown): string | null {
25
- if (typeof path !== "string" || !path.trim()) {
27
+ export function normalizeRelPath(path: JsonValue | undefined): string | null {
28
+ if (!isString(path) || !path.trim()) {
26
29
  return null;
27
30
  }
28
31
  let p = path.trim().replaceAll("\\", "/");
@@ -42,10 +45,10 @@ export function normalizeRelPath(path: unknown): string | null {
42
45
  * The refusal a tool returns for a path {@link normalizeRelPath} rejected, quoting what the model
43
46
  * sent so it can see what to change.
44
47
  *
45
- * @param {unknown} path
48
+ * @param {JsonValue | undefined} path The tool argument as the model sent it.
46
49
  * @returns {ToolResult}
47
50
  */
48
- export function invalidPathResult(path: unknown): ToolResult {
51
+ export function invalidPathResult(path: JsonValue | undefined): ToolResult {
49
52
  return {
50
53
  success: false,
51
54
  error: `Invalid path ${JSON.stringify(path)} — use a path relative to the project root (no leading "/", no "..").`,
Binary file
@@ -3,27 +3,36 @@
3
3
  *
4
4
  * After a mutation passes schema validation, this module attempts a lightweight headless render
5
5
  * (buildScope → renderNode into a throwaway div) and reports render-time errors back through the
6
- * same { ok, error } shape that applyAndValidate consumes. The model can then self-correct
7
- * within the round budget instead of the user discovering a blank canvas.
6
+ * same { ok, error } shape that applyAndValidate consumes. The model can then self-correct within
7
+ * the round budget instead of the user discovering a blank canvas.
8
8
  *
9
- * v1 scope: catches render throws only (missing $ref, malformed Function body, bad template
9
+ * V1 scope: catches render throws only (missing $ref, malformed Function body, bad template
10
10
  * expressions). Does NOT detect empty/zero-node output or deep-render custom element internals
11
11
  * (connectedCallback doesn't fire on detached nodes).
12
12
  *
13
13
  * @license MIT
14
14
  */
15
15
 
16
- import { buildScope, renderNode, runScoped, setSkipServerFunctions } from "@jxsuite/runtime";
16
+ import {
17
+ buildScope,
18
+ renderNode,
19
+ runScoped,
20
+ setResolveToken,
21
+ setSkipServerFunctions,
22
+ setTemplateErrorHandler,
23
+ } from "@jxsuite/runtime";
17
24
  import type { JxDocument } from "@jxsuite/schema/types";
25
+ import { hostResolveToken } from "../canvas/canvas-origin";
18
26
 
19
27
  /**
20
28
  * Translate a render-time error into an actionable message the model can fix.
21
29
  *
22
- * @param {Error} err
30
+ * @param {unknown} cause What the render threw — an Error in practice; anything else is printed
31
+ * as-is.
23
32
  * @returns {string}
24
33
  */
25
- function translateRenderError(err: Error): string {
26
- const msg = err.message || String(err);
34
+ function translateRenderError(cause: unknown): string {
35
+ const msg = (cause instanceof Error && cause.message) || String(cause);
27
36
 
28
37
  if (msg.includes("is not defined") || msg.includes("Cannot read properties of")) {
29
38
  return `Render error: ${msg}\n → Fix: A $ref or template expression references a name that doesn't exist in state. Check that all $ref paths and \${...} expressions match entries in the document's "state" object.`;
@@ -51,8 +60,17 @@ export async function renderCheck(
51
60
  doc: JxDocument,
52
61
  ): Promise<{ ok: true } | { ok: false; error: string }> {
53
62
  let stopRender: (() => void) | null = null;
63
+ /* A binding that throws no longer unwinds the render (spec.md §6.1) — it renders empty and waits
64
+ for its data — so the throw is collected here instead. The first one is the verdict: a page
65
+ whose template can never evaluate is exactly what this check exists to refuse. */
66
+ const bindingErrors: Error[] = [];
67
+ setTemplateErrorHandler((error) => {
68
+ bindingErrors.push(error);
69
+ });
54
70
  try {
55
71
  setSkipServerFunctions(true);
72
+ // The desktop dev proxy refuses a class resolve without the token the canvas carries.
73
+ setResolveToken(hostResolveToken());
56
74
 
57
75
  const state = await buildScope(doc, {});
58
76
 
@@ -62,10 +80,12 @@ export async function renderCheck(
62
80
  });
63
81
  stopRender = stop;
64
82
 
65
- return { ok: true };
83
+ const [first] = bindingErrors;
84
+ return first ? { ok: false, error: translateRenderError(first) } : { ok: true };
66
85
  } catch (error) {
67
- return { ok: false, error: translateRenderError(error as Error) };
86
+ return { ok: false, error: translateRenderError(error) };
68
87
  } finally {
88
+ setTemplateErrorHandler(null);
69
89
  // Dispose all effects created synchronously by renderNode via the RUNTIME's runScoped — scope
70
90
  // Collection is per @vue/reactivity module instance, so a studio effectScope here would collect
71
91
  // Nothing. Effects from the async buildScope (prototype/computed setup) still escape the scope;
@@ -2,23 +2,23 @@
2
2
  * The settings registry — every application setting Studio holds, declared once.
3
3
  *
4
4
  * Before this table the answer to "which settings roam, and what is each one's default" lived in
5
- * four places: a `PERSISTED_SETTINGS_KEYS` array, a private `const` per key in each `*-settings.ts`,
6
- * a bespoke getter/setter pair beside it, and whatever the getter's `||` happened to fall back to.
7
- * Adding a roaming setting meant editing all four and hoping; the key strings themselves were
8
- * duplicated between the array and the module that owned them.
5
+ * four places: a `PERSISTED_SETTINGS_KEYS` array, a private `const` per key in each
6
+ * `*-settings.ts`, a bespoke getter/setter pair beside it, and whatever the getter's `||` happened
7
+ * to fall back to. Adding a roaming setting meant editing all four and hoping; the key strings
8
+ * themselves were duplicated between the array and the module that owned them.
9
9
  *
10
10
  * Two properties of this table are load-bearing rather than tidy:
11
11
  *
12
- * 1. **Scope is declared, not inferred.** {@link USER_SETTINGS} is DERIVED from it, so a setting
13
- * roams because it says `scope: "user"` — not because someone remembered to add its key to a
14
- * second list. `device` is the honest name for the rest: panel geometry and a palette's MRU
15
- * describe *this window*, and a user with two windows open wants them to differ.
16
- * 2. **A default is not a value.** The default is what a *reader* sees when nothing is stored; it
17
- * is never itself stored. `getModel()` used to mask unset as `"gpt-4o"` with `||`, a form
18
- * prefilled from it, and Save wrote the mask back — which is how an install whose owner had
19
- * configured an entirely different provider was left holding `jx.ai.model: "gpt-4o"` and
20
- * nothing else. {@link readSetting} and {@link readStoredSetting} in `kernel.ts` are two
21
- * functions for exactly this reason.
12
+ * 1. **Scope is declared, not inferred.** {@link USER_SETTINGS} is DERIVED from it, so a setting roams
13
+ * because it says `scope: "user"` — not because someone remembered to add its key to a second
14
+ * list. `device` is the honest name for the rest: panel geometry and a palette's MRU describe
15
+ * _this window_, and a user with two windows open wants them to differ.
16
+ * 2. **A default is not a value.** The default is what a _reader_ sees when nothing is stored; it is
17
+ * never itself stored. `getModel()` used to mask unset as `"gpt-4o"` with `||`, a form prefilled
18
+ * from it, and Save wrote the mask back — which is how an install whose owner had configured an
19
+ * entirely different provider was left holding `jx.ai.model: "gpt-4o"` and nothing else.
20
+ * {@link readSetting} and {@link readStoredSetting} in `kernel.ts` are two functions for exactly
21
+ * this reason.
22
22
  *
23
23
  * @license MIT
24
24
  */
@@ -144,6 +144,17 @@ export const SETTINGS = {
144
144
  normalize: trimmed,
145
145
  scope: "user",
146
146
  },
147
+ /**
148
+ * Whether the Design rail draws the developer panels — Files and Packages (`specs/studio.md`
149
+ * §5.1). Unset, the default, keeps them off the rail; `settings/developer-panels.ts` reads it.
150
+ * Roams, for the reason `showIgnoredFiles` does: it is a way of working, not a window's.
151
+ */
152
+ developerPanels: {
153
+ default: "",
154
+ key: "jx.panels.developer",
155
+ normalize: trimmed,
156
+ scope: "user",
157
+ },
147
158
  cfAccountId: {
148
159
  default: "",
149
160
  key: "jx.cf.accountId",
@@ -35,13 +35,22 @@ import type { SettingsPatch } from "./write-queue";
35
35
  /** The synchronous source of truth. Absent key means unset — which is not the same as `""`. */
36
36
  const values = new Map<string, string>();
37
37
 
38
+ /**
39
+ * The cache, when this realm has one. `lib.dom` declares `localStorage` unconditionally, but a
40
+ * realm without a DOM (Bun under test, a worker) has none — so it is looked up on every use, inside
41
+ * the caller's `try`, where an access that throws (storage disabled) is already handled.
42
+ */
43
+ function cacheStorage(): Storage | undefined {
44
+ return typeof localStorage === "undefined" ? undefined : localStorage;
45
+ }
46
+
38
47
  /** Mirror a value into the cache, so the next boot is correct before the backend answers. */
39
48
  function writeCache(key: string, value: string | null): void {
40
49
  try {
41
50
  if (value === null) {
42
- globalThis.localStorage?.removeItem(key);
51
+ cacheStorage()?.removeItem(key);
43
52
  } else {
44
- globalThis.localStorage?.setItem(key, value);
53
+ cacheStorage()?.setItem(key, value);
45
54
  }
46
55
  } catch {
47
56
  /* Storage unavailable (private mode) — the Map still serves this session. */
@@ -60,7 +69,7 @@ function writeCache(key: string, value: string | null): void {
60
69
  */
61
70
  try {
62
71
  for (const definition of ALL_SETTINGS) {
63
- const cached = globalThis.localStorage?.getItem(definition.key);
72
+ const cached = cacheStorage()?.getItem(definition.key);
64
73
  if (cached !== null && cached !== undefined) {
65
74
  values.set(definition.key, cached);
66
75
  }
@@ -120,7 +129,7 @@ function announce(keys: readonly string[]): void {
120
129
  // ─── Writing ──────────────────────────────────────────────────────────────────
121
130
 
122
131
  const queue = createWriteQueue({
123
- onError(error: unknown) {
132
+ onError(error) {
124
133
  notify("error", "Your settings could not be saved.", {
125
134
  detail: error instanceof Error ? error.message : String(error),
126
135
  key: "settings-write",
@@ -2,18 +2,18 @@
2
2
  * A coalescing, serializing write queue.
3
3
  *
4
4
  * The defect it exists to make unrepresentable: saving a provider mutates three settings through
5
- * three setters, and each setter used to fire its own whole-map write. Three overlapping writes went
6
- * out against one file, each reading storage at a different moment, with no ordering between them —
7
- * so whichever landed last won. That was observed in the wild as a settings file holding
5
+ * three setters, and each setter used to fire its own whole-map write. Three overlapping writes
6
+ * went out against one file, each reading storage at a different moment, with no ordering between
7
+ * them — so whichever landed last won. That was observed in the wild as a settings file holding
8
8
  * `{"jx.ai.model": "gpt-4o"}`: the SECOND of three snapshots, landing last, a state storage itself
9
9
  * never rested in.
10
10
  *
11
11
  * Two rules, and they are different guarantees:
12
12
  *
13
- * 1. **Coalesce.** Every mutation in one synchronous burst merges into a single patch, sent once
14
- * the burst has finished. N setters produce one write, not N.
15
- * 2. **Serialize.** At most one send is in flight. A mutation made while one is out waits for it
16
- * rather than racing it, so the order the app made changes in is the order the store sees them.
13
+ * 1. **Coalesce.** Every mutation in one synchronous burst merges into a single patch, sent once the
14
+ * burst has finished. N setters produce one write, not N.
15
+ * 2. **Serialize.** At most one send is in flight. A mutation made while one is out waits for it
16
+ * rather than racing it, so the order the app made changes in is the order the store sees them.
17
17
  *
18
18
  * Generic over the transport so the kernel can hand it a platform call and a test can hand it an
19
19
  * array. `schedule` is injectable for the same reason.
@@ -34,7 +34,7 @@ export interface WriteQueueOptions {
34
34
  /** Deliver one merged patch. Rejection is reported through {@link WriteQueueOptions.onError}. */
35
35
  send: (patch: SettingsPatch) => Promise<void>;
36
36
  /** Called with the failure and the patch that did not land. */
37
- onError?: (error: unknown, patch: SettingsPatch) => void;
37
+ onError?: (cause: unknown, patch: SettingsPatch) => void;
38
38
  /**
39
39
  * Defer to the end of the current burst. Defaults to `queueMicrotask`.
40
40
  *
@@ -89,7 +89,7 @@ export function createWriteQueue(opts: WriteQueueOptions): WriteQueue {
89
89
  }
90
90
  tail = tail
91
91
  .then(() => opts.send(patch))
92
- .catch((error: unknown) => {
92
+ .catch((error) => {
93
93
  opts.onError?.(error, patch);
94
94
  });
95
95
  return tail;
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import type { JxMutableNode } from "@jxsuite/schema/types";
9
- import { displayTagName } from "@jxsuite/schema/guards";
9
+ import { displayTagName, isNonNullObject, isString } from "@jxsuite/schema/guards";
10
10
 
11
11
  interface TokenLintFinding {
12
12
  path: string;
@@ -25,7 +25,8 @@ interface TokenLintFinding {
25
25
  function buildTokenIndex(projectStyle: Record<string, string>) {
26
26
  const index = new Map<string, string>();
27
27
  for (const [key, value] of Object.entries(projectStyle)) {
28
- if (!key.startsWith("--") || typeof value !== "string") {
28
+ // The style object comes from `project.json`, where a key can also hold a nested block.
29
+ if (!key.startsWith("--") || !isString(value)) {
29
30
  continue;
30
31
  }
31
32
  const norm = value.toLowerCase().trim();
@@ -43,7 +44,7 @@ function buildTokenIndex(projectStyle: Record<string, string>) {
43
44
  * @returns {boolean}
44
45
  */
45
46
  function isTokenRef(value: string) {
46
- return typeof value === "string" && value.includes("var(--");
47
+ return value.includes("var(--");
47
48
  }
48
49
 
49
50
  /**
@@ -53,7 +54,7 @@ function isTokenRef(value: string) {
53
54
  * @returns {boolean}
54
55
  */
55
56
  function isTemplate(value: string) {
56
- return typeof value === "string" && value.includes("${");
57
+ return value.includes("${");
57
58
  }
58
59
 
59
60
  /**
@@ -78,18 +79,19 @@ export function flagHardcodedTokens(
78
79
 
79
80
  const findings: TokenLintFinding[] = [];
80
81
 
81
- function walk(node: unknown, pathPrefix: string) {
82
- if (!node || typeof node !== "object") {
82
+ /* Every member is re-checked rather than trusted: callers hand over model output parsed from
83
+ JSON, so a "node" may be a primitive, a `style` may be a string, and a child may be anything. */
84
+ function walk(el: JxMutableNode, pathPrefix: string) {
85
+ if (!isNonNullObject(el)) {
83
86
  return;
84
87
  }
85
- const el = node as JxMutableNode;
86
88
 
87
- if (el.style && typeof el.style === "object") {
89
+ if (isNonNullObject(el.style)) {
88
90
  for (const [prop, val] of Object.entries(el.style)) {
89
91
  if (prop.startsWith("@")) {
90
92
  continue;
91
93
  }
92
- if (typeof val !== "string") {
94
+ if (!isString(val)) {
93
95
  continue;
94
96
  }
95
97
  if (isTokenRef(val) || isTemplate(val)) {
@@ -112,7 +114,7 @@ export function flagHardcodedTokens(
112
114
  if (Array.isArray(el.children)) {
113
115
  for (let i = 0; i < el.children.length; i++) {
114
116
  const child = el.children[i];
115
- if (child && typeof child === "object") {
117
+ if (isNonNullObject(child)) {
116
118
  walk(child, `${pathPrefix} > ${displayTagName(child.tagName) || `[${i}]`}`);
117
119
  }
118
120
  }
@@ -20,7 +20,7 @@
20
20
 
21
21
  import type { createChatState } from "@jxsuite/ai/chat-state";
22
22
  import { DEFAULT_TURN_POLICY, runTurn } from "@jxsuite/ai/harness";
23
- import type { TurnRun } from "@jxsuite/ai/harness";
23
+ import type { TurnInput, TurnRun } from "@jxsuite/ai/harness";
24
24
  import { toChatMessages, toOpenAITools } from "@jxsuite/ai/messages";
25
25
  import type { StreamingClient } from "@jxsuite/ai/streaming-client";
26
26
  import { createSessionFacts } from "@jxsuite/ai/tools";
@@ -36,6 +36,9 @@ import { studioTurnHooks } from "./harness/turn-hooks";
36
36
  /** What a turn that drew nothing says: the model answered with neither text nor a tool call. */
37
37
  export const EMPTY_TURN_TEXT = DEFAULT_TURN_POLICY.emptyText;
38
38
 
39
+ /** {@link TurnInput} while this module assembles it: read-only to `runTurn`, not to its builder. */
40
+ type TurnInputDraft = { -readonly [K in keyof TurnInput]: TurnInput[K] };
41
+
39
42
  interface RunAgentLoopOptions {
40
43
  chatState: ReturnType<typeof createChatState>;
41
44
  streamingClient: StreamingClient;
@@ -94,7 +97,7 @@ export async function runAgentLoop({
94
97
  let superseded = false;
95
98
  let run: TurnRun | undefined;
96
99
  try {
97
- run = runTurn({
100
+ const input: TurnInputDraft = {
98
101
  history,
99
102
  system: [{ text: systemPrompt }],
100
103
  /* Projected from the chat store, the transcript of record. The streaming client is read on
@@ -104,13 +107,15 @@ export async function runAgentLoop({
104
107
  chatState.toMessagesArray(),
105
108
  toOpenAITools(request.tools),
106
109
  systemPrompt,
110
+ /* SAFETY: the one production caller, `document-assistant.ts`, always passes its turn
111
+ controller's signal; only tests that drive the loop directly omit it, and their stream
112
+ doubles record the absent signal rather than reading it — which the agent-trace
113
+ goldens (`signal: "none"`) pin. */
107
114
  signal as AbortSignal,
108
115
  ),
109
116
  modelInfo: { family: "openai-compat", model: chatState.model },
110
117
  tools: toolRegistry,
111
- ...(signal ? { signal } : {}),
112
118
  turnId: ledger.turnId,
113
- ...(placeholder ? { firstMessageId: placeholder.id } : {}),
114
119
  policy: { estimateTokens: estimatePromptTokens },
115
120
  hooks: studioTurnHooks({
116
121
  superseded: () =>
@@ -128,7 +133,14 @@ export async function runAgentLoop({
128
133
  applyHarnessEvent(chatState, event);
129
134
  }
130
135
  },
131
- });
136
+ };
137
+ if (signal) {
138
+ input.signal = signal;
139
+ }
140
+ if (placeholder) {
141
+ input.firstMessageId = placeholder.id;
142
+ }
143
+ run = runTurn(input);
132
144
  await run.outcome;
133
145
  } finally {
134
146
  endBatch();