@jxsuite/studio 5.3.0 → 5.4.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 (389) hide show
  1. package/data/css-meta.json +28 -27
  2. package/dist/chunks/{cf-account-picker-nwnwdm6p.js → cf-account-picker-3f08rry6.js} +21 -18
  3. package/dist/chunks/{cf-settings-adg74qsk.js → cf-settings-m79r7p5y.js} +4 -4
  4. package/dist/chunks/{components-5y78e05d.js → components-xm826zjw.js} +3 -3
  5. package/dist/chunks/{content-source-4rzvmp0m.js → content-source-jt7rbcbc.js} +22 -22
  6. package/dist/chunks/{convert-to-repeater-jxsv62v7.js → convert-to-repeater-vg38bq99.js} +22 -22
  7. package/dist/chunks/{editor-3qhbg51x.js → editor-ddy019sn.js} +2 -2
  8. package/dist/chunks/entry-commands-64nb2a9a.js +42 -0
  9. package/dist/chunks/{extension-sections-2mrptyek.js → extension-sections-r73an5s6.js} +30 -29
  10. package/dist/chunks/{file-ops-knfqshrm.js → file-ops-3xan8mnj.js} +21 -21
  11. package/dist/chunks/{files-y6fr4he9.js → files-egsb0ry8.js} +28 -28
  12. package/dist/chunks/{format-host-1k4qrcqd.js → format-host-mym8qnd0.js} +3 -3
  13. package/dist/chunks/{fs-events-3y6y0nrm.js → fs-events-z2gg8qjt.js} +4 -4
  14. package/dist/chunks/{git-panel-2rkrsjva.js → git-panel-a05atk6q.js} +20 -20
  15. package/dist/chunks/{grid-view-1p6hsyjx.css → grid-view-3g1h2re8.css} +956 -139
  16. package/dist/chunks/{grid-view-a7b87n2c.js → grid-view-qaqer9kr.js} +24 -24
  17. package/dist/chunks/{icons-yy10wk9r.js → icons-drxq9q10.js} +8 -2
  18. package/dist/chunks/{iframe-host-scpw01h8.js → iframe-host-psetcv20.js} +11 -11
  19. package/dist/chunks/{index-n4j7qxyr.js → index-9yjae3hz.js} +4 -4
  20. package/dist/chunks/{javascript-4abzjcy9.css → javascript-bc9z461d.css} +688 -54
  21. package/dist/chunks/{javascript-xvrfrpkb.js → javascript-hr5sg57n.js} +2 -2
  22. package/dist/chunks/{jsonMode-vvmpmk34.css → jsonMode-qqd9nm1t.css} +1120 -303
  23. package/dist/chunks/{jsonMode-tyx2kj6p.js → jsonMode-zs88v0wr.js} +4 -4
  24. package/dist/chunks/layers-panel-83a16ytx.js +41 -0
  25. package/dist/chunks/{layers-jnvdbqva.js → layers-s6mc01ry.js} +3 -3
  26. package/dist/chunks/{media-picker-f66nav16.js → media-picker-nhn6rv4w.js} +11 -11
  27. package/dist/chunks/{menu-1dfhry4s.js → menu-8j4qxjrp.js} +4 -4
  28. package/dist/chunks/{monaco-binding-sw6en4dw.js → monaco-binding-e8d9wzyk.js} +3 -3
  29. package/dist/chunks/{monaco-buffer-pykwbm92.js → monaco-buffer-jaq1t9zj.js} +2 -2
  30. package/dist/chunks/{monaco-setup-8vbyqnhr.css → monaco-setup-ey9cjcm3.css} +954 -137
  31. package/dist/chunks/{monaco-setup-km6abc6q.js → monaco-setup-gsjdysze.js} +6 -6
  32. package/dist/chunks/{platform-ts9cg1a4.js → platform-fnchmhy7.js} +5 -3
  33. package/dist/chunks/publish-panel-ak6hxfma.js +27 -0
  34. package/dist/chunks/quick-search-c63mkt3b.js +47 -0
  35. package/dist/chunks/{references-h69xp9zz.js → references-f7bdv3z5.js} +3 -3
  36. package/dist/chunks/right-panel-t5n8wttg.js +45 -0
  37. package/dist/chunks/{studio-ze46gzjh.js → studio-01269reb.js} +7 -7
  38. package/dist/chunks/{studio-rnyf3f8e.js → studio-0a4gncx0.js} +3 -3
  39. package/dist/chunks/{studio-e1f24eff.js → studio-0d4p4wxj.js} +6778 -2993
  40. package/dist/chunks/{studio-4wbb9ct0.js → studio-1tejxvba.js} +3006 -1855
  41. package/dist/chunks/{studio-d1n2bykn.js → studio-3nprwbd9.js} +117 -25
  42. package/dist/chunks/{studio-4c041r8y.js → studio-40z39dme.js} +3 -3
  43. package/dist/chunks/{studio-151w0xnh.js → studio-482eeazk.js} +20 -20
  44. package/dist/chunks/{studio-cgprcdxn.js → studio-4998spet.js} +10 -9
  45. package/dist/chunks/{studio-nq5yf5mp.js → studio-557bmn0x.js} +2 -2
  46. package/dist/chunks/{studio-rtskkm43.js → studio-5w26wza5.js} +3 -3
  47. package/dist/chunks/{studio-6nzaktvy.js → studio-6pwn9j8c.js} +6 -3
  48. package/dist/chunks/{studio-wnsyffg1.js → studio-6vg0x5fz.js} +3 -2
  49. package/dist/chunks/{studio-vn5hske5.js → studio-7d3c1m59.js} +12 -5
  50. package/dist/chunks/{studio-6gryj0sg.js → studio-9vsvz7w7.js} +6 -6
  51. package/dist/chunks/{studio-50wfwy44.js → studio-9wm0xzpf.js} +19 -19
  52. package/dist/chunks/{studio-0j7r7s9g.js → studio-ag3z6shb.js} +10 -4
  53. package/dist/chunks/studio-aj9drheq.js +177 -0
  54. package/dist/chunks/{studio-xajk70w0.js → studio-apv9x70c.js} +189 -130
  55. package/dist/chunks/{studio-c04nzbby.js → studio-b9q3znz8.js} +2 -2
  56. package/dist/chunks/{studio-nfx354t1.js → studio-bh47w0cy.js} +9 -10
  57. package/dist/chunks/{studio-gk2twyh4.js → studio-dgdm6vvt.js} +264 -52
  58. package/dist/chunks/{studio-gtfq1dkz.js → studio-dwdcr2e8.js} +4 -4
  59. package/dist/chunks/{studio-nqgawfks.js → studio-fbcyz234.js} +146 -139
  60. package/dist/chunks/{studio-27q131j3.js → studio-fqpkpq1t.js} +7 -4
  61. package/dist/chunks/{studio-c0qgc3tn.js → studio-fy320dfc.js} +62 -68
  62. package/dist/chunks/{studio-zjjde71a.js → studio-gjj4bbfx.js} +2 -2
  63. package/dist/chunks/{studio-g33v4fe9.js → studio-jfhxy8h3.js} +7 -7
  64. package/dist/chunks/{studio-ab87phj1.js → studio-kwewmhhq.js} +4 -4
  65. package/dist/chunks/{studio-7rrb1esn.js → studio-m58xn8at.js} +25 -24
  66. package/dist/chunks/{studio-fzjx96t2.js → studio-mfkh1q8d.js} +17 -17
  67. package/dist/chunks/{studio-drg8qj9k.js → studio-mrh0a92f.js} +17 -17
  68. package/dist/chunks/{studio-jt27ta6x.js → studio-mt79tn56.js} +3 -3
  69. package/dist/chunks/{studio-b66rsh78.js → studio-ne593z1j.js} +38 -31
  70. package/dist/chunks/{studio-h4nvnjvz.js → studio-ptfcxkz5.js} +418 -232
  71. package/dist/chunks/{studio-dd1qqkry.js → studio-qxye31h7.js} +7 -7
  72. package/dist/chunks/{studio-ye9drbk8.js → studio-rav5bpmp.js} +73 -52
  73. package/dist/chunks/{studio-6kvgrkrp.js → studio-rwmmbrth.js} +6 -6
  74. package/dist/chunks/{studio-b7xacrwe.js → studio-sceg8ws0.js} +8 -8
  75. package/dist/chunks/{studio-msc1ee1m.js → studio-sjas5b3a.js} +19 -13
  76. package/dist/chunks/{studio-a65w20ex.js → studio-vd67b66d.js} +3 -3
  77. package/dist/chunks/{studio-7144epdr.js → studio-w475cbf9.js} +10 -10
  78. package/dist/chunks/{studio-4f3psrk1.js → studio-w7gpcvfj.js} +9 -9
  79. package/dist/chunks/{studio-nsgw7dbk.js → studio-xrbfdxgk.js} +7 -7
  80. package/dist/chunks/{studio-ke09tn9k.js → studio-y49b6mjv.js} +35 -35
  81. package/dist/chunks/{studio-j0w60gft.js → studio-ygvr9e4q.js} +10 -10
  82. package/dist/chunks/{studio-z2smx5ce.js → studio-yxmmjy2a.js} +9 -6
  83. package/dist/chunks/{tsMode-jy4m86rv.js → tsMode-ay4c78ne.js} +4 -4
  84. package/dist/chunks/{tsMode-hnxxb73h.css → tsMode-c72wyz27.css} +954 -137
  85. package/dist/chunks/{workspace-np10mayv.js → workspace-b9k2frks.js} +5 -5
  86. package/dist/chunks/{ws-client-ny4zc51r.js → ws-client-erze4czt.js} +356 -20
  87. package/dist/codicon.ttf +0 -0
  88. package/dist/iframe-entry.js +18 -16
  89. package/dist/studio.css +956 -139
  90. package/dist/studio.js +1453 -830
  91. package/dist/workers/editor.worker.js +196 -107
  92. package/dist/workers/json.worker.js +196 -107
  93. package/dist/workers/ts.worker.js +196 -107
  94. package/package.json +15 -14
  95. package/src/about/about-modal.ts +4 -3
  96. package/src/browse/library-commands.ts +15 -13
  97. package/src/browse/library-pane.ts +2 -2
  98. package/src/canvas/canvas-render.ts +97 -83
  99. package/src/canvas/canvas-surface.ts +2 -2
  100. package/src/canvas/canvas-utils.ts +42 -32
  101. package/src/canvas/diff-toolbar.ts +21 -2
  102. package/src/canvas/diff-view.ts +30 -6
  103. package/src/canvas/iframe-entry.ts +2 -2
  104. package/src/canvas/iframe-host.ts +5 -5
  105. package/src/canvas/iframe-interaction.ts +7 -6
  106. package/src/canvas/iframe-overlay.ts +1 -1
  107. package/src/canvas/iframe-protocol.ts +6 -5
  108. package/src/canvas/iframe-render.ts +3 -3
  109. package/src/canvas/popover-state.ts +1 -1
  110. package/src/canvas/stage-scrollbar.ts +112 -0
  111. package/src/canvas/surface-registry.ts +9 -2
  112. package/src/collab/collab-commands.ts +8 -6
  113. package/src/collab/collab-session.ts +4 -4
  114. package/src/collab/collab-state.ts +4 -4
  115. package/src/collab/presence-chips.ts +3 -3
  116. package/src/commands/app-commands.ts +7 -7
  117. package/src/commands/budget.ts +17 -16
  118. package/src/commands/command-args.ts +10 -9
  119. package/src/commands/context.ts +20 -10
  120. package/src/commands/defaults.ts +30 -29
  121. package/src/commands/levels.ts +8 -6
  122. package/src/commands/live-context.ts +12 -10
  123. package/src/commands/reference.ts +5 -5
  124. package/src/commands/registry.ts +2 -2
  125. package/src/content/draft-state.ts +9 -8
  126. package/src/content/entry-commands.ts +16 -14
  127. package/src/content/entry-editor.ts +2 -2
  128. package/src/content/entry-fields.ts +1 -1
  129. package/src/editor/context-menu.ts +4 -4
  130. package/src/editor/convert-to-component.ts +6 -5
  131. package/src/editor/inline-edit.ts +3 -3
  132. package/src/editor/shortcuts.ts +88 -20
  133. package/src/editor/slash-menu.ts +11 -10
  134. package/src/files/elements.ts +4 -5
  135. package/src/files/file-ops.ts +1 -1
  136. package/src/files/files.ts +21 -17
  137. package/src/files/serialize-document.ts +1 -1
  138. package/src/format/convert-file.ts +5 -5
  139. package/src/github/github-auth-status.ts +107 -0
  140. package/src/github/github-auth.ts +18 -82
  141. package/src/github/github-publish.ts +7 -6
  142. package/src/grid/cell-editors.ts +8 -7
  143. package/src/grid/grid-layout.ts +1 -1
  144. package/src/grid/grid-open.ts +6 -5
  145. package/src/grid/grid-panel.ts +13 -12
  146. package/src/grid/redirects-grid.ts +14 -11
  147. package/src/grid/redirects.ts +10 -5
  148. package/src/grid/sources/content-source.ts +10 -9
  149. package/src/hosting/document.ts +28 -1
  150. package/src/hosting/stage.ts +15 -4
  151. package/src/i18n/i18n-commands.ts +9 -7
  152. package/src/new-project/location-fields.ts +16 -3
  153. package/src/new-project/new-project-modal.ts +23 -7
  154. package/src/page-params.ts +6 -6
  155. package/src/panels/activity-panel.ts +11 -10
  156. package/src/panels/ai-chat/chat-view.ts +27 -14
  157. package/src/panels/ai-chat/composer.ts +10 -3
  158. package/src/panels/ai-panel.ts +87 -29
  159. package/src/panels/block-action-bar.ts +59 -33
  160. package/src/panels/bottom-dock.ts +22 -22
  161. package/src/panels/data-explorer.ts +9 -9
  162. package/src/panels/data-grid.ts +1 -1
  163. package/src/panels/editors.ts +8 -8
  164. package/src/panels/elements-panel.ts +7 -8
  165. package/src/panels/empty-state.ts +1 -1
  166. package/src/panels/events-panel.ts +13 -12
  167. package/src/panels/formula-workspace.ts +8 -5
  168. package/src/panels/frontmatter-fields.ts +4 -1
  169. package/src/panels/frontmatter-panel.ts +18 -18
  170. package/src/panels/git-panel.ts +19 -13
  171. package/src/panels/head-panel.ts +9 -10
  172. package/src/panels/i18n-panel.ts +6 -4
  173. package/src/panels/imports-panel.ts +1 -1
  174. package/src/panels/jump-bar.ts +20 -18
  175. package/src/panels/layers-panel.ts +19 -17
  176. package/src/panels/left-panel.ts +3 -3
  177. package/src/panels/navigator-panels.ts +8 -8
  178. package/src/panels/overlays.ts +1 -1
  179. package/src/panels/pane-context.ts +56 -28
  180. package/src/panels/pane-grid.ts +9 -8
  181. package/src/panels/panel-registry.ts +47 -19
  182. package/src/panels/problems-panel.ts +11 -12
  183. package/src/panels/properties-panel.ts +21 -20
  184. package/src/panels/provenance.ts +3 -3
  185. package/src/panels/quick-search.ts +15 -11
  186. package/src/panels/right-panel.ts +4 -3
  187. package/src/panels/seo-modal.ts +5 -4
  188. package/src/panels/settings-menu.ts +9 -9
  189. package/src/panels/settings-pane.ts +3 -3
  190. package/src/panels/signals-panel.ts +16 -9
  191. package/src/panels/statement-editor.ts +12 -9
  192. package/src/panels/style-panel.ts +45 -41
  193. package/src/panels/stylebook-panel.ts +0 -1
  194. package/src/panels/tab-strip.ts +26 -23
  195. package/src/platform-errors.ts +2 -2
  196. package/src/platform.ts +44 -4
  197. package/src/platforms/cloud.ts +11 -1
  198. package/src/platforms/default-platform.ts +141 -4
  199. package/src/platforms/devserver.ts +23 -3
  200. package/src/publish/deploy-checklist.ts +11 -10
  201. package/src/publish/publish-commands.ts +9 -8
  202. package/src/services/a11y-report.ts +1 -1
  203. package/src/services/ai-ask.ts +39 -16
  204. package/src/services/ai-command-tools.ts +28 -14
  205. package/src/services/ai-import-tools.ts +43 -29
  206. package/src/services/ai-project-tools.ts +20 -38
  207. package/src/services/ai-settings.ts +55 -2
  208. package/src/services/ai-tools.ts +69 -58
  209. package/src/services/ai-write-report.ts +4 -4
  210. package/src/services/ai-writes.ts +74 -55
  211. package/src/services/automation.ts +12 -12
  212. package/src/services/clock.ts +2 -1
  213. package/src/services/connection.ts +2 -2
  214. package/src/services/context-manager.ts +69 -6
  215. package/src/services/directory-picker.ts +93 -27
  216. package/src/services/document-assistant.ts +86 -17
  217. package/src/services/gated-registry.ts +4 -3
  218. package/src/services/idle.ts +5 -4
  219. package/src/services/live-surfaces.ts +2 -1
  220. package/src/services/notify.ts +9 -7
  221. package/src/services/popover-report.ts +3 -3
  222. package/src/services/preview-eval.ts +1 -1
  223. package/src/services/project-adoption.ts +34 -1
  224. package/src/services/project-path.ts +53 -0
  225. package/src/services/settings/kernel.ts +13 -2
  226. package/src/services/tool-executor.ts +135 -30
  227. package/src/services/tool-outcomes.ts +143 -0
  228. package/src/settings/contexts-section.ts +8 -8
  229. package/src/settings/contributed-section.ts +6 -6
  230. package/src/settings/css-vars-editor.ts +6 -5
  231. package/src/settings/extension-commands.ts +19 -18
  232. package/src/settings/extension-sections.ts +7 -7
  233. package/src/settings/extensions-section.ts +3 -3
  234. package/src/settings/general-settings.ts +21 -18
  235. package/src/settings/preferences-accounts.ts +3 -3
  236. package/src/settings/preferences-dialog.ts +9 -8
  237. package/src/settings/preferences-sections.ts +1 -1
  238. package/src/settings/project-sections.ts +2 -2
  239. package/src/settings/section-registry.ts +7 -6
  240. package/src/settings/settings-document.ts +41 -43
  241. package/src/shell/tree.ts +29 -0
  242. package/src/shell.ts +63 -55
  243. package/src/site-context.ts +1 -1
  244. package/src/store.ts +2 -2
  245. package/src/studio.ts +46 -28
  246. package/src/style/live-preview.ts +8 -8
  247. package/src/style/project-styles.ts +8 -9
  248. package/src/style/token-ref.ts +2 -2
  249. package/src/surfaces/about.json +6 -2
  250. package/src/surfaces/add-repo.json +2 -2
  251. package/src/surfaces/add-repo.ts +2 -2
  252. package/src/surfaces/ai-chat.json +14 -6
  253. package/src/surfaces/ai-chat.ts +4 -2
  254. package/src/surfaces/ai-credentials-form.json +53 -49
  255. package/src/surfaces/ai-credentials-form.ts +18 -4
  256. package/src/surfaces/ai-managed-connect.json +4 -4
  257. package/src/surfaces/block-action-bar.json +4 -4
  258. package/src/surfaces/block-action-bar.ts +3 -3
  259. package/src/surfaces/boot-failure.json +228 -0
  260. package/src/surfaces/boot-failure.ts +156 -0
  261. package/src/surfaces/bottom-dock.json +1 -1
  262. package/src/surfaces/canvas-stage.json +9 -40
  263. package/src/surfaces/canvas-stage.ts +9 -9
  264. package/src/surfaces/cf-account-picker.json +11 -8
  265. package/src/surfaces/commandbar.ts +11 -10
  266. package/src/surfaces/convert-repeater.ts +3 -2
  267. package/src/surfaces/dialog.json +7 -1
  268. package/src/surfaces/dialog.ts +2 -2
  269. package/src/surfaces/doc-header.json +6 -13
  270. package/src/surfaces/doc-header.ts +4 -5
  271. package/src/surfaces/entry-editor.json +1 -1
  272. package/src/surfaces/entry-editor.ts +2 -1
  273. package/src/surfaces/expression-editor.json +5 -5
  274. package/src/surfaces/files-panel.json +4 -3
  275. package/src/surfaces/files-panel.ts +1 -1
  276. package/src/surfaces/formula-palette.json +2 -2
  277. package/src/surfaces/formula-palette.ts +1 -1
  278. package/src/surfaces/git-panel.json +167 -109
  279. package/src/surfaces/git-panel.ts +2 -2
  280. package/src/surfaces/github-auth.json +2 -1
  281. package/src/surfaces/github-publish.ts +3 -3
  282. package/src/surfaces/grid-open.json +1 -1
  283. package/src/surfaces/grid-panel.json +2 -2
  284. package/src/surfaces/grid-views.json +1 -1
  285. package/src/surfaces/inspector-dock.json +2 -2
  286. package/src/surfaces/jump-bar.json +1 -1
  287. package/src/surfaces/jump-bar.ts +1 -1
  288. package/src/surfaces/library-pane.ts +2 -1
  289. package/src/surfaces/logic-panel.json +7 -7
  290. package/src/surfaces/logic-panel.ts +6 -4
  291. package/src/surfaces/logic-workspace.json +2 -2
  292. package/src/surfaces/logic-workspace.ts +2 -2
  293. package/src/surfaces/media-browser.ts +3 -3
  294. package/src/surfaces/media-pane.ts +2 -1
  295. package/src/surfaces/menu.ts +5 -5
  296. package/src/surfaces/new-project.json +1 -1
  297. package/src/surfaces/pane-context.json +86 -57
  298. package/src/surfaces/pane-context.ts +2 -1
  299. package/src/surfaces/pane-grid.json +3 -3
  300. package/src/surfaces/panel-activity.json +2 -1
  301. package/src/surfaces/panel-deploy-checklist.json +1 -1
  302. package/src/surfaces/panel-elements.ts +2 -1
  303. package/src/surfaces/panel-i18n.ts +2 -1
  304. package/src/surfaces/panel-outline.json +1 -1
  305. package/src/surfaces/panel-outline.ts +4 -3
  306. package/src/surfaces/panel-page.json +2 -2
  307. package/src/surfaces/panel-page.ts +4 -1
  308. package/src/surfaces/panel-problems.json +4 -3
  309. package/src/surfaces/panel-problems.ts +2 -2
  310. package/src/surfaces/panel-signals.json +23 -8
  311. package/src/surfaces/panel-signals.ts +5 -1
  312. package/src/surfaces/panel-stylebook-layers.json +1 -1
  313. package/src/surfaces/panel-stylebook-layers.ts +2 -2
  314. package/src/surfaces/preferences.json +21 -8
  315. package/src/surfaces/preferences.ts +9 -1
  316. package/src/surfaces/properties-panel.json +4 -4
  317. package/src/surfaces/properties-panel.ts +2 -2
  318. package/src/surfaces/publish.json +1 -1
  319. package/src/surfaces/publish.ts +2 -1
  320. package/src/surfaces/push-plan.json +4 -3
  321. package/src/surfaces/rail.json +2 -2
  322. package/src/surfaces/rail.ts +10 -4
  323. package/src/surfaces/reference-field.json +1 -1
  324. package/src/surfaces/schema-form.json +2 -2
  325. package/src/surfaces/schema-form.ts +1 -1
  326. package/src/surfaces/seo.json +1 -1
  327. package/src/surfaces/seo.ts +2 -2
  328. package/src/surfaces/settings-contributed.ts +2 -1
  329. package/src/surfaces/settings-css-vars.json +4 -4
  330. package/src/surfaces/settings-deploy.json +4 -4
  331. package/src/surfaces/settings-deploy.ts +2 -1
  332. package/src/surfaces/settings-extensions.json +6 -6
  333. package/src/surfaces/settings-extensions.ts +6 -2
  334. package/src/surfaces/settings-locales.json +4 -4
  335. package/src/surfaces/settings-overview.ts +2 -1
  336. package/src/surfaces/settings-pane.ts +3 -2
  337. package/src/surfaces/settings-rawjson.ts +1 -1
  338. package/src/surfaces/slash-menu.ts +4 -4
  339. package/src/surfaces/statements.json +3 -3
  340. package/src/surfaces/statusbar.ts +23 -23
  341. package/src/surfaces/style-panel.json +9 -5
  342. package/src/surfaces/style-panel.ts +3 -3
  343. package/src/surfaces/tab-strip.json +2 -2
  344. package/src/surfaces/target-line.json +1 -1
  345. package/src/surfaces/target-line.ts +12 -10
  346. package/src/surfaces/welcome.json +7 -2
  347. package/src/tabs/doc-op-apply.ts +5 -5
  348. package/src/tabs/patch-ops.ts +3 -3
  349. package/src/tabs/project-config.ts +10 -10
  350. package/src/tabs/selection.ts +1 -1
  351. package/src/tabs/tab.ts +13 -14
  352. package/src/tabs/transact.ts +18 -24
  353. package/src/types.ts +27 -3
  354. package/src/ui/ai-credentials-form.ts +74 -16
  355. package/src/ui/ai-managed-connect.ts +68 -19
  356. package/src/ui/color-selector.ts +1 -1
  357. package/src/ui/expression-editor.ts +3 -3
  358. package/src/ui/form-controls.ts +6 -5
  359. package/src/ui/formula-catalog.ts +4 -4
  360. package/src/ui/formula-chips.ts +2 -2
  361. package/src/ui/layers.ts +20 -18
  362. package/src/ui/panel-resize.ts +5 -5
  363. package/src/ui/popover-surface.ts +2 -2
  364. package/src/ui/progress-modal.ts +3 -3
  365. package/src/ui/regions.ts +14 -9
  366. package/src/ui/schema-form.ts +10 -9
  367. package/src/ui/timing.ts +9 -7
  368. package/src/ui/value-source.ts +4 -4
  369. package/src/ui/virtual-window.ts +1 -1
  370. package/src/utils/base64.ts +20 -1
  371. package/src/utils/canvas-media.ts +1 -1
  372. package/src/utils/studio-utils.ts +0 -31
  373. package/src/view.ts +4 -3
  374. package/src/workspace/pane-derive.ts +14 -13
  375. package/src/workspace/session.ts +7 -6
  376. package/src/workspace/workspace.ts +49 -39
  377. package/styles/canvas.css +1 -27
  378. package/styles/inspector.css +4 -3
  379. package/styles/overlays.css +1 -1
  380. package/styles/tokens.css +17 -1
  381. package/styles/tokens.json +6 -1
  382. package/dist/chunks/entry-commands-1wnsqn5d.js +0 -42
  383. package/dist/chunks/layers-panel-73gfkcga.js +0 -41
  384. package/dist/chunks/publish-panel-z1zd2da1.js +0 -27
  385. package/dist/chunks/quick-search-zdv7h8ht.js +0 -47
  386. package/dist/chunks/right-panel-889vbnm5.js +0 -45
  387. package/dist/chunks/studio-727xh0e3.js +0 -76
  388. package/src/files/json-layout.ts +0 -474
  389. package/src/services/ai-turn-signal.ts +0 -70
@@ -2,15 +2,15 @@
2
2
  /**
3
3
  * The Content tab — everything about WHAT this element is and says.
4
4
  *
5
- * Plan §6.5 re-split the inspector by task. Content is the element itself (tag, id, class, text),
6
- * its HTML attributes, its link target, its custom attributes, its component props and its media.
7
- * Three things left, and each left for a place that already had a better claim on it:
5
+ * The Inspector is split by task (§6). Content is the element itself (tag, id, class, text), its
6
+ * HTML attributes, its link target, its custom attributes, its component props and its media. Three
7
+ * things left, and each left for a place that already had a better claim on it:
8
8
  *
9
9
  * - **Repeater · Switch · Observed Attributes · CSS Properties · CSS Parts → the Logic tab.** Wiring
10
10
  * a `$switch` and wiring a click handler are the same task (`panels/events-panel.ts`).
11
11
  * - **The Page section → the Document Header card.** `panels/head-panel.ts` owns the one layout
12
12
  * picker; this panel drew a second one that could disagree with it.
13
- * - **Media breakpoint DEFINITIONS → Project Settings › Contexts** (P4). Nothing remains here: the
13
+ * - **Media breakpoint DEFINITIONS → Project Settings › Contexts** (§17.1). Nothing remains here: the
14
14
  * only reason adding a breakpoint used to cost you your element selection.
15
15
  *
16
16
  * **This module decides; `surfaces/properties-panel.json` draws.** Every question with an answer —
@@ -27,7 +27,7 @@
27
27
  * untouched, and there is nothing to guard against. What survives is the DRAFT layer
28
28
  * (`ui/field-input.ts`), which is a different promise — it is what keeps a half-typed value from
29
29
  * being replaced by the last committed one, and what keys that half-typed value to the NODE rather
30
- * than to the field's name (§11.4).
30
+ * than to the field's name (§6.1).
31
31
  *
32
32
  * **Two leaves are drawn elsewhere**, and each is its own surface with readers outside this tab:
33
33
  * the media picker and the expression editor. The document draws an empty `[part="control-host"]`
@@ -220,11 +220,12 @@ function bindingDonor(value: unknown): string {
220
220
  /**
221
221
  * The state entry a bound value reads, when the chip can name one — a `$ref` or a `${…}` template.
222
222
  *
223
- * §6.2's table says a bound chip "click opens the source", and on the Content tab it did not: both
223
+ * §6.7's table says clicking a bound chip opens its source, and on the Content tab it did not: both
224
224
  * bound branches returned a `donor` and a `title` and no `onClick`, so the chip was drawn as a
225
- * handler-less span. The Style tab's chip has jumped to the Data panel since P5; the same promise
226
- * on the other tab was a label. Same regex as `style-panel.ts`'s `templateSignalOf`, because both
227
- * spellings of a template (`${x}` and `${state.x}`) name the same entry.
225
+ * handler-less span. The Style tab's chip has jumped to the Data panel since the shell redesign's
226
+ * inspector phase; the same promise on the other tab was a label. Same regex as `style-panel.ts`'s
227
+ * `templateSignalOf`, because both spellings of a template (`${x}` and `${state.x}`) name the same
228
+ * entry.
228
229
  */
229
230
  function boundSignalOf(value: unknown): string | null {
230
231
  if (isRef(value)) {
@@ -285,7 +286,7 @@ export function isComponentDefinitionOpen(node: JxMutableNode): boolean {
285
286
  }
286
287
 
287
288
  /**
288
- * Which of §6.2's four states a component-prop row is in.
289
+ * Which of §6.7's four states a component-prop row is in.
289
290
  *
290
291
  * Bound beats set (a `$ref` IS a value, but "bound to `title`" is the more useful sentence); set
291
292
  * beats inherited; a prop with no declared default and no value is plain Default and draws
@@ -322,7 +323,7 @@ function componentPropProvenance(
322
323
  return { state: "default" };
323
324
  }
324
325
 
325
- /** Which of §6.2's states an HTML-attribute row is in. Attributes have no third cascade layer. */
326
+ /** Which of §6.7's states an HTML-attribute row is in. Attributes have no third cascade layer. */
326
327
  function attributeProvenance(
327
328
  attr: string,
328
329
  value: unknown,
@@ -453,9 +454,9 @@ export function invalidatePageRouteCache() {
453
454
  * refuse a section the user is looking at; no validation at all would accept the label the old
454
455
  * `inspector.toggleSection` step passed ("Element", not `__element`) and silently do nothing.
455
456
  *
456
- * `__media` left with the breakpoint definitions, which are Project Settings › Contexts now (P4).
457
- * `__observed`, `__cssprops` and `__cssparts` are drawn by the Logic tab; the key space is the
458
- * INSPECTOR's, not one tab's, so `inspector.setSection` keeps addressing all of them.
457
+ * `__media` left with the breakpoint definitions, which are Project Settings › Contexts now
458
+ * (§17.1). `__observed`, `__cssprops` and `__cssparts` are drawn by the Logic tab; the key space is
459
+ * the INSPECTOR's, not one tab's, so `inspector.setSection` keeps addressing all of them.
459
460
  */
460
461
  export const INSPECTOR_SECTION_KEYS = [
461
462
  "__element",
@@ -881,7 +882,7 @@ function commitKvPair(key: string): void {
881
882
  write(name, value);
882
883
  }
883
884
 
884
- /** The rung picker: every source this position permits, one action away (§6.3). */
885
+ /** The rung picker: every source this position permits, one action away (§6.6). */
885
886
  function openSourceMenu(key: string, anchor: HTMLElement): void {
886
887
  const ladder = plans.get(key)?.ladder;
887
888
  if (!ladder) {
@@ -1143,7 +1144,7 @@ function projectPanel(): ContentPanelView {
1143
1144
  }
1144
1145
 
1145
1146
  // A repeating list has no content of its own — it has a source and a template, and both are
1146
- // Wiring. Content says where the answer lives rather than drawing an empty accordion (§6.5).
1147
+ // Wiring. Content says where the answer lives rather than drawing an empty accordion (§6).
1147
1148
  if (node.$prototype === "Array") {
1148
1149
  return emptyView(
1149
1150
  "A repeating list has no content of its own.",
@@ -1286,7 +1287,7 @@ function sectionsFor(node: JxMutableNode, path: JxPath): ContentSectionView[] {
1286
1287
  }
1287
1288
 
1288
1289
  /**
1289
- * One accordion section, with §6.2's collapsed-header tally.
1290
+ * One accordion section, with §6.7's collapsed-header tally.
1290
1291
  *
1291
1292
  * The dot is an INDICATOR and not a control: it used to inherit `.set-dot`'s pointer cursor and its
1292
1293
  * danger hover, which together say "click me to clear this", and nothing happened because it never
@@ -1464,7 +1465,7 @@ function elementRows(
1464
1465
  // ─── Component settings ──────────────────────────────────────────────────────
1465
1466
 
1466
1467
  /**
1467
- * Component props, each row carrying §6.2's provenance chip — the SECOND cascade.
1468
+ * Component props, each row carrying §6.7's provenance chip — the SECOND cascade.
1468
1469
  *
1469
1470
  * A component instance's value for a prop either overrides the component's declared default or does
1470
1471
  * not exist, and until the chip landed the two were the same blank field. The chip states which,
@@ -1646,7 +1647,7 @@ function attributeRow(
1646
1647
  const hasVal = value !== undefined && value !== "";
1647
1648
  const key = `attr|${attr}`;
1648
1649
  const label = attrLabel(entry, attr);
1649
- // One write per selected element, inside ONE transaction (§6.5). `targets` is `[path]` for a
1650
+ // One write per selected element, inside ONE transaction (§6.7). `targets` is `[path]` for a
1650
1651
  // Single selection, so this is the same single mutation it has always been.
1651
1652
  const commitAttr = (v?: JsonValue) =>
1652
1653
  transactDoc(activeTab.value!, (t) => {
@@ -1887,7 +1888,7 @@ function customRows(path: JxPath, customAttrs: [string, unknown][]): ContentRowV
1887
1888
  return rows;
1888
1889
  }
1889
1890
 
1890
- // ─── Usage (§9.6) ────────────────────────────────────────────────────────────
1891
+ // ─── Usage (§9.1.1) ──────────────────────────────────────────────────────────
1891
1892
 
1892
1893
  /**
1893
1894
  * The component instance's usage line — "Used on 7 pages →", expanding to the files.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Provenance — where the value in a field came from, as one chip (plan §6.2).
2
+ * Provenance — where the value in a field came from, as one chip (§6.7).
3
3
  *
4
4
  * Four states, and the two that carry information NAME THEIR SOURCE:
5
5
  *
@@ -12,7 +12,7 @@
12
12
  * | mixed | neutral, "mixed (3)" — see below | clear across all |
13
13
  *
14
14
  * **Mixed** is what a multi-selection says when the selected elements disagree about a field
15
- * (§6.5). It is a fifth state of THIS chip rather than a fifth widget, because it answers the same
15
+ * (§6.7). It is a fifth state of THIS chip rather than a fifth widget, because it answers the same
16
16
  * question the other four answer — _where did the value in this box come from?_ — and the honest
17
17
  * answer is "from several places, and they differ". It names how many elements are involved, so
18
18
  * "mixed" never has to mean "some unknown number of things". Typing into a Mixed field commits the
@@ -38,7 +38,7 @@
38
38
  * looks. That is the split the header above always described; it is now the whole file.
39
39
  */
40
40
 
41
- /** The states of §6.2 (four) plus §6.5's `mixed`, in the order the table lists them. */
41
+ /** §6.7's four chip states plus its multi-selection `mixed`, in the order the table lists them. */
42
42
  export type ProvenanceState = "set" | "inherited" | "default" | "bound" | "mixed";
43
43
 
44
44
  /** Where one field's value came from, and what clicking the chip does about it. */
@@ -1,19 +1,20 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
- * The Palette — one omnibox, several modes (UX-REDESIGN-PLAN §5.4).
3
+ * The Palette — one omnibox, several modes (specs/studio.md §13; its rendering rules are
4
+ * specs/studio-ui-guidelines.md §12).
4
5
  *
5
6
  * This file used to be a filename-substring finder with one hidden domain swap in it: with no
6
7
  * project open the same trigger, the same chrome and the same placeholder silently listed recent
7
8
  * PROJECTS instead. It is now the surface the whole shell shrinks into — the place a capability
8
- * goes when it is retired from the chrome (§2 principle 9), which only works if everything is
9
- * reachable here by name, with its chord printed beside it.
9
+ * goes when it is retired from the chrome (the chrome budget, specs/studio-ui-guidelines.md §12.2),
10
+ * which only works if everything is reachable here by name, with its chord printed beside it.
10
11
  *
11
12
  * Four properties earn that:
12
13
  *
13
14
  * 1. **Modes are named, prefixed and enumerable.** `>` commands, `@` document nodes, plain text files,
14
15
  * and `?` lists them. The mode is echoed as a REMOVABLE CHIP, so the no-project case is a stated
15
16
  * `Recent Projects` mode rather than a swap you have to infer. `PALETTE_MODES` is the namespace:
16
- * P4's Problems and P7's content search are new members, not a new widget.
17
+ * a Problems mode or a content search is a new member, not a new widget.
17
18
  * 2. **Files are matched by fuzzy subsequence over the FULL PATH.** `pgblog` finds
18
19
  * `pages/blog/index.md`. The backend glob (`**\/*q*.{json,md}`) can only do a basename
19
20
  * substring, so the palette asks it once for the document set and ranks locally — which is also
@@ -22,11 +23,11 @@
22
23
  * 3. **Every row prints its binding.** That is how a large surface stays discoverable without adding
23
24
  * chrome, and it is the mechanism by which the palette teaches the keyboard it replaced.
24
25
  * 4. **An unavailable command is GREYED, not hidden**, with its `requires` sentence as the subtitle
25
- * (§2 principle 4). "Why can't I" is the question a palette is uniquely good at answering, and a
26
- * row that vanishes answers it with silence.
26
+ * (`studio-ui-guidelines.md` §12.3). "Why can't I" is the question a palette is uniquely good at
27
+ * answering, and a row that vanishes answers it with silence.
27
28
  *
28
29
  * The exported names still read `…QuickSearch` because `src/studio.ts` and `src/panels/empty-state.
29
- * ts` import them and neither is this workstream's file. They are the palette's; the rename is one
30
+ * ts` import them and neither was this change's file. They are the palette's; the rename is one
30
31
  * find-replace in those two call sites.
31
32
  */
32
33
 
@@ -60,7 +61,10 @@ export interface PaletteModeSpec {
60
61
  /** The removable chip's text, and the row label in `?`. */
61
62
  chip: string;
62
63
  placeholder: string;
63
- /** What `?` prints under the mode's name. One sentence, no noun phrases (§2 principle 6). */
64
+ /**
65
+ * What `?` prints under the mode's name. One sentence, no noun phrases (`studio-ui-guidelines.md`
66
+ * §11.1).
67
+ */
64
68
  description: string;
65
69
  }
66
70
 
@@ -341,7 +345,7 @@ interface ProjectRow {
341
345
  interface CommandRow {
342
346
  kind: "command";
343
347
  id: string;
344
- /** `"View: Zen Mode"` — the palette's own naming convention (§5.1). */
348
+ /** `"View: Zen Mode"` — the palette's own naming convention (§13.1). */
345
349
  name: string;
346
350
  /** The `requires` sentence when disabled; otherwise empty. */
347
351
  detail: string;
@@ -519,8 +523,8 @@ function projectRows(query: string): ProjectRow[] {
519
523
  /**
520
524
  * Every command the registry holds, ranked — including the ones that cannot run right now.
521
525
  *
522
- * Visibility (`when`) still hides; enablement does not. That split is the whole of §2 principle 4:
523
- * a command that does not apply to this app at all is absent, and one that does not apply to this
526
+ * Visibility (`when`) still hides; enablement does not. That split is the whole of §13.1's pair: a
527
+ * command that does not apply to this app at all is absent, and one that does not apply to this
524
528
  * MOMENT is greyed and says why.
525
529
  */
526
530
  function commandRows(registry: CommandRegistry, query: string): CommandRow[] {
@@ -4,8 +4,9 @@
4
4
  *
5
5
  * **Content · Style · Logic · Assistant**, text-labelled. Three of those are renames of what was
6
6
  * here (Properties→Content, Events→Logic) and the fourth is the assistant, folded in from the fifth
7
- * grid column it used to own — which is the point of plan §3.2 ⑨: an inspector tab costs zero
8
- * additional width, so the canvas gets the ~300px back and the assistant is still one key away.
7
+ * grid column it used to own — which is the point of §3.1's "no assistant column": an inspector tab
8
+ * costs zero additional width, so the canvas gets the ~300px back and the assistant is still one
9
+ * key away.
9
10
  *
10
11
  * **This file no longer draws anything.** The dock's markup, its ARIA and its style are
11
12
  * `surfaces/inspector-dock.json`, mounted through `surfaces/inspector-dock.ts`; what is left here
@@ -176,7 +177,7 @@ export function mount(ctx: RightPanelCtx) {
176
177
  // Track properties the right panel reads
177
178
  void tab.doc.document;
178
179
  // The whole SET, joined — a bare property read would not re-trigger when the selection
179
- // Changes WITHIN the array, and §6.5's helpers always replace it but nothing enforces that.
180
+ // Changes WITHIN the array, and §6.7's helpers always replace it but nothing enforces that.
180
181
  void tab.session.selection.map((path) => path.join("/")).join("|");
181
182
  void tab.session.ui.rightTab;
182
183
  }
@@ -11,7 +11,7 @@
11
11
  * So it opens as a modal, from two places — the Document Header card and the Navigator's Page
12
12
  * panel. Two doors because the two are different moments: one while writing the page, one while
13
13
  * working on its head material. Both run `document.openSeo`, so there is a third door in the
14
- * palette and no surface owns the capability (§2 principle 1).
14
+ * palette and no surface owns the capability (one definition site per action, §13).
15
15
  *
16
16
  * **The card keeps the fields; the modal keeps the picture.** Title still lives on the card,
17
17
  * because it is the one head value you type while writing. Everything the modal holds is either a
@@ -72,7 +72,7 @@ import type { AnyCommand, CommandRegistry } from "../commands/registry";
72
72
  * Two rendered previews, a resolved-field list and a warning list, over the MERGED head — and no
73
73
  * score. A number out of a hundred aggregates unrelated facts into a verdict, and a verdict is
74
74
  * what gets optimised; a count beside a limit and a named consequence say the same thing without
75
- * ranking anything (plan §9.2, §14).
75
+ * ranking anything (§16.6).
76
76
  *
77
77
  * The previews are pictures of what the build emits, so a value the page did not author is marked
78
78
  * as inherited with the donor NAMED — the third cascade to use `panels/provenance.ts`'s vocabulary
@@ -87,7 +87,7 @@ import type { AnyCommand, CommandRegistry } from "../commands/registry";
87
87
  * The two chips that can go somewhere do: a value from the site's own `$head` opens Project
88
88
  * Settings › Site head, and one from the site `name` opens Overview. The layout and build donors
89
89
  * get no handler, because the card has no verb for "open that layout" and a control that looks
90
- * pressable and does nothing is the defect §6.2 exists to remove — the document draws those two as
90
+ * pressable and does nothing is the defect §6.7 exists to remove — the document draws those two as
91
91
  * a `<span>` and the two below as a `<button>`, on exactly this answer.
92
92
  *
93
93
  * @param {SeoField} field
@@ -550,7 +550,8 @@ export function seoCommands(): AnyCommand[] {
550
550
  group: "2_document",
551
551
  requires: "an open document",
552
552
  when: (ctx) => ctx.document.open,
553
- /* No `aiTool`, by §12.4's first deletion rule: this opens a modal for a person. */
553
+ /* No `aiTool`, by `studio-ui-guidelines.md` §12.4's first rule: this opens a modal for a
554
+ person. */
554
555
  run: () => {
555
556
  const tab = activeTab.value;
556
557
  if (!tab) {
@@ -7,15 +7,15 @@
7
7
  * `app.preferences` (the application, ⌘,) and `settings.open` (this project, ⌘⇧,) — plus a third
8
8
  * editor over the same project document, `styles.open`. A slot can hold one of those and must lie
9
9
  * about the rest by omission. A menu can hold all three and say what each one is, because it prints
10
- * every row's own name, chord and gate beside it (§12.3). That is the whole argument for the matrix
11
- * row `settings/menu` admitting two levels, and for the divider this file draws where the level
12
- * changes.
10
+ * every row's own name, chord and gate beside it (`studio-ui-guidelines.md` §12.3). That is the
11
+ * whole argument for the matrix row `settings/menu` admitting two levels, and for the divider this
12
+ * file draws where the level changes.
13
13
  *
14
14
  * **Nothing here is a list of actions.** The rows are `registry.forPlacement("settings/menu")`, so
15
15
  * a record joins the menu by declaring the placement and leaves by not declaring it. The submenus
16
16
  * are the enumeration of each parent command's own `section` ARGUMENT, read from that argument's
17
17
  * own definition site — which is state the command already validates, not a second vocabulary
18
- * (§12.5).
18
+ * (`studio-ui-guidelines.md` §12.5).
19
19
  *
20
20
  * **A parent row runs its own command AND owns a submenu.** The APG menu pattern does not describe
21
21
  * that and Spectrum's stock submenu forbade it outright; the kit's `jx-menu-item` makes it the rule
@@ -67,11 +67,11 @@ let _rerender: (() => void) | null = null;
67
67
  /**
68
68
  * A command's `section` argument, enumerated from that argument's OWN definition site.
69
69
  *
70
- * NOT the second list of actions §12.5 forbids: it holds no titles, no handlers and no ordering of
71
- * its own. Each entry points at the array the command's validation already reads —
72
- * `app.preferences` refuses anything `isPreferencesSection` rejects, `settings.open` refuses
73
- * anything absent from `settingsSectionKeys()` — so a submenu row can never name a value its own
74
- * command would refuse.
70
+ * NOT the second list of actions `studio-ui-guidelines.md` §12.5 forbids: it holds no titles, no
71
+ * handlers and no ordering of its own. Each entry points at the array the command's validation
72
+ * already reads — `app.preferences` refuses anything `isPreferencesSection` rejects,
73
+ * `settings.open` refuses anything absent from `settingsSectionKeys()` — so a submenu row can never
74
+ * name a value its own command would refuse.
75
75
  */
76
76
  const SECTION_SOURCES: Readonly<Record<string, () => readonly MenuSection[]>> = {
77
77
  "app.preferences": () =>
@@ -6,7 +6,7 @@
6
6
  * two-column shape the modal had, because the modal's IA was never the problem — its MODALITY was.
7
7
  * Moving the identical layout into `#canvas-wrap` is what makes the seven screenshot crops change
8
8
  * frame (`overlay.dialog:settings` → `pane.primary`) without one manifest STEP changing, which is
9
- * §13.7's proof that the command boundary was drawn in the right place.
9
+ * the proof that the command boundary was drawn in the right place.
10
10
  *
11
11
  * **This file is the FLOW; the markup is a document.** `surfaces/settings-pane.json` owns the two
12
12
  * columns, the list's ARIA and keyboard, and every value in their style;
@@ -74,8 +74,8 @@ interface ActiveSettingsPane {
74
74
  * section rendering into that same element throws on a part whose markers have left the document.
75
75
  * It fails the other way too: lit renders BESIDE foreign nodes rather than replacing them, so a
76
76
  * lit section drawn after a document one left both on screen at once. A fresh host per section is
77
- * what makes the two kinds coexist, which is the whole of §9.3's surface-level rule applied to
78
- * one dispatcher.
77
+ * what makes the two kinds coexist, which is the whole of `studio-ui-guidelines.md` §9.3's
78
+ * surface-level rule applied to one dispatcher.
79
79
  */
80
80
  sectionHost: HTMLElement | null;
81
81
  /** The section the body currently holds, so an idle re-render does not rebuild it. */
@@ -147,8 +147,8 @@ export interface SignalDef {
147
147
  * The rename that was refused, and why — cleared by the next accepted one.
148
148
  *
149
149
  * A collision used to be a silent no-op: the field kept the typed name, the document kept the old
150
- * one, and nothing said which had won. Plan §11.2 asks for "collision-checked rename with a visible
151
- * error", and half of that had shipped.
150
+ * one, and nothing said which had won. The shell redesign asked for "collision-checked rename with
151
+ * a visible error", and half of that had shipped.
152
152
  */
153
153
  let renameError: { name: string; message: string } | null = null;
154
154
 
@@ -1139,7 +1139,7 @@ function emitsField(name: string, def: SignalDef): SignalFieldView {
1139
1139
  /**
1140
1140
  * A function: what it is for, what it takes, what it emits, and its body.
1141
1141
  *
1142
- * Structured bodies (spec §20) are a body MODE rather than a new entity: "Statements" is the
1142
+ * Structured bodies (`spec.md` §20) are a body MODE rather than a new entity: "Statements" is the
1143
1143
  * statement-card editor over `body: JxStatement[]`, "Code" is the text path over `body: string`.
1144
1144
  * Switching modes replaces the body with the other representation's empty seed — an explicit mode
1145
1145
  * change, nothing is converted.
@@ -1189,13 +1189,19 @@ function functionFields(S: SignalsPanelState, name: string, def: SignalDef): Sig
1189
1189
  prop: "Body",
1190
1190
  segments: [
1191
1191
  {
1192
+ checked: statements ? "true" : "false",
1192
1193
  field: "body",
1193
1194
  key: "statements",
1194
1195
  label: "Statements",
1195
- selected: statements,
1196
1196
  signal: name,
1197
1197
  },
1198
- { field: "body", key: "code", label: "Code", selected: !statements, signal: name },
1198
+ {
1199
+ checked: statements ? "false" : "true",
1200
+ field: "body",
1201
+ key: "code",
1202
+ label: "Code",
1203
+ signal: name,
1204
+ },
1199
1205
  ],
1200
1206
  signal: name,
1201
1207
  },
@@ -1850,9 +1856,10 @@ function definedSignalNames(): string[] {
1850
1856
  /**
1851
1857
  * Open a state entry's formula in the Bottom dock.
1852
1858
  *
1853
- * It used to be an XPath press matching the row's RENDERED NAME, which plan §13's R1 forbids
1854
- * outright: a panel that starts eliding long names, or grouping differently, breaks a shot by
1855
- * improving the app. The document defines these names, so the document is what validates them.
1859
+ * It used to be an XPath press matching the row's RENDERED NAME, which R1
1860
+ * (`scripts/screenshots/README.md`) forbids outright: a panel that starts eliding long names, or
1861
+ * grouping differently, breaks a shot by improving the app. The document defines these names, so
1862
+ * the document is what validates them.
1856
1863
  *
1857
1864
  * It defaults its target to the one open Data row — the button it replaces is rendered inside that
1858
1865
  * entry's own editor, so "the one that is open" is what a reader means, and with several open it
@@ -1943,7 +1950,7 @@ export function registerSignalsCommands(registry: CommandRegistry): void {
1943
1950
  }
1944
1951
 
1945
1952
  /* THE STATE PANEL IS GONE, AND ITS EDITOR IS IN DATA — `panels/data-explorer.ts`.
1946
- It was registered here `rail: false`, waiting for plan §11.2's merge into Data, and the merge did
1953
+ It was registered here `rail: false`, waiting for its merge into Data (§5.6), and the merge did
1947
1954
  not follow: the button was removed and the editor was left reachable only by typing "State" into
1948
1955
  the palette. Declaring a state variable — or a component property, which is a state entry with a
1949
1956
  default — is not an advanced move to hide behind a search box, so the entry list is now the Data
@@ -1,7 +1,7 @@
1
1
  /// <reference lib="dom" />
2
- // oxlint-disable unicorn/no-thenable -- `then` is the JSON Schema conditional keyword (spec §20), not a promise
2
+ // oxlint-disable unicorn/no-thenable -- `then` is the JSON Schema conditional keyword (spec.md §20), not a promise
3
3
  /**
4
- * Statement editor (spec §20) — the FLOW behind the `statements` surface.
4
+ * Statement editor (`spec.md` §20) — the FLOW behind the `statements` surface.
5
5
  *
6
6
  * A Function entry's `body: JxStatement[]` is edited here as structure rather than as text: bare
7
7
  * expression nodes (mutation or `call`), `if`/`then`/`else` branches, `$switch`/`cases` multiway
@@ -27,8 +27,8 @@
27
27
  * paints them.
28
28
  * - **The add-statement control is a menu, not a picker.** It was an `sp-picker` that had to reset
29
29
  * its own value to `""` inside its change handler so the placeholder came back. A document's
30
- * binding skips an equal write, so that trick cannot work here — and it should not have to: §12.5
31
- * asks for one list of actions, and the kit's menu is it.
30
+ * binding skips an equal write, so that trick cannot work here — and it should not have to:
31
+ * `studio-ui-guidelines.md` §12.5 asks for one list of actions, and the kit's menu is it.
32
32
  *
33
33
  * @docs studio/logic/statements
34
34
  */
@@ -91,7 +91,7 @@ type LanePath = (string | number)[];
91
91
 
92
92
  // ─── Statement Kind Detection ────────────────────────────────────────────────
93
93
 
94
- /** Discriminate a statement's kind, mirroring the runtime's detection order (spec §20.2). */
94
+ /** Discriminate a statement's kind, mirroring the runtime's detection order (`spec.md` §20.2). */
95
95
  export function statementKind(stmt: unknown): "expression" | "if" | "switch" | "dispatch" {
96
96
  if (isJsonObject(stmt)) {
97
97
  if ("operator" in stmt) {
@@ -112,7 +112,7 @@ export function statementKind(stmt: unknown): "expression" | "if" | "switch" | "
112
112
 
113
113
  const ASSIGN_OPS = new Set(["=", "+=", "-=", "*=", "/="]);
114
114
 
115
- /** Card header label — ECMA/WHATWG naming (spec §20.2). */
115
+ /** Card header label — ECMA/WHATWG naming (`spec.md` §20.2). */
116
116
  function kindLabel(stmt: unknown): string {
117
117
  switch (statementKind(stmt)) {
118
118
  case "if": {
@@ -137,7 +137,7 @@ function kindLabel(stmt: unknown): string {
137
137
  }
138
138
  }
139
139
 
140
- // ─── Add-statement Seeds (spec §20 shapes) ───────────────────────────────────
140
+ // ─── Add-statement Seeds (spec.md §20 shapes) ────────────────────────────────
141
141
 
142
142
  const STATEMENT_SEEDS: Record<string, () => JxStatement> = {
143
143
  call: () => ({ operator: "call", target: { $ref: "" }, value: [] }),
@@ -150,7 +150,10 @@ const STATEMENT_SEEDS: Record<string, () => JxStatement> = {
150
150
  switch: () => ({ $switch: { $ref: "" }, cases: {} }),
151
151
  };
152
152
 
153
- /** The add-statement menu, in the order the rows read. One list, and this is it (§12.5). */
153
+ /**
154
+ * The add-statement menu, in the order the rows read. One list, and this is it
155
+ * (`studio-ui-guidelines.md` §12.5).
156
+ */
154
157
  const STATEMENT_CHOICES: readonly StatementOption[] = [
155
158
  { label: "Set state", value: "set" },
156
159
  { label: "Call function", value: "call" },
@@ -753,7 +756,7 @@ function markDrop(row: HTMLElement, type?: string): void {
753
756
  const islandHosts = new WeakMap<HTMLElement, Map<string, HTMLElement>>();
754
757
 
755
758
  /**
756
- * Draw a structured function body (spec §20) into `host`, or bring the one already there up to
759
+ * Draw a structured function body (`spec.md` §20) into `host`, or bring the one already there up to
757
760
  * date. `onChange` receives a fresh statement array on every edit; the input array is never
758
761
  * mutated.
759
762
  *