@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
@@ -1,11 +1,11 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
- * ⑪ The Bottom dock — where long operations and lists of things-to-fix live (plan §3.2 ⑪).
3
+ * The Bottom dock — where long operations and lists of things-to-fix live (§16.3).
4
4
  *
5
5
  * Studio had no bottom dock and at least five surfaces wanted one, so each of them took over the
6
6
  * canvas: Code mode, the git diff, the formula workspace and the Monaco function editor all replace
7
- * the stage, and the progress modal covers the whole app. The canvas is the one region §3 says must
8
- * never disappear, so this is where those surfaces go instead.
7
+ * the stage, and the progress modal covers the whole app. The canvas is the one region §16.3 says
8
+ * must never disappear, so this is where those surfaces go instead.
9
9
  *
10
10
  * **Under the pane grid, not under the window.** The dock occupies the pane's grid column only, so
11
11
  * opening it never narrows the Navigator or the Inspector — which is the difference between a dock
@@ -13,16 +13,17 @@
13
13
  *
14
14
  * **Three tabs, under a cap of four.** `scripts/check-chrome-budget.ts` caps a dock at four, and
15
15
  * this spends three: **Problems · Logic · Activity**, with Deploy folded into Activity because a
16
- * deploy is a long operation with a log. Diff was the fourth until P8 gave it a pane to open into
17
- * instead — see {@link registerBottomPanels}. `shell.ts` declares the ids ({@link BOTTOM_TAB_IDS})
18
- * so a bare Bun process can read `view.setBottomTab`'s enum; this module turns them into records.
16
+ * deploy is a long operation with a log. Diff was the fourth until a second pane gave it somewhere
17
+ * to open into instead — see {@link registerBottomPanels}. `shell.ts` declares the ids
18
+ * ({@link BOTTOM_TAB_IDS}) so a bare Bun process can read `view.setBottomTab`'s enum; this module
19
+ * turns them into records.
19
20
  *
20
21
  * **The tabs are panel records, so they inherit everything.** `dock: "bottom"` was already admitted
21
22
  * by `registerPanel()` and by the level × placement matrix, and `ui/regions.ts` has parsed
22
- * `dock.bottom` since P3 — it simply resolved to nothing, because there was no host. This is the
23
- * host. Every tab gets `dock.bottom/panel:<id>` for free and its title comes from the record.
23
+ * `dock.bottom` from the start — it simply resolved to nothing, because there was no host. This is
24
+ * the host. Every tab gets `dock.bottom/panel:<id>` for free and its title comes from the record.
24
25
  *
25
- * **Logic is built, and it is why this dock exists.** P8.5 moves the formula workspace and the
26
+ * **Logic is built, and it is why this dock exists.** §16.3 moves the formula workspace and the
26
27
  * Monaco function editor out of their canvas takeovers and into this tab, so the page whose values
27
28
  * they compute stays on screen beside them. Its record is defined beside the surface
28
29
  * (`panels/formula-workspace.ts`) and registered from here, like Problems and Activity. Because a
@@ -30,11 +31,10 @@
30
31
  * for a Logic target appearing and opens the dock on it — once per target, so closing the dock over
31
32
  * an open formula keeps it closed until you open another.
32
33
  *
33
- * **Problems is one of them.** §7.2's table places it here ("Problems | Bottom dock ⑪, badge on the
34
- * rail") and this dock is its only host. It keeps a rail button and a badge — the rail groups by
35
- * LEVEL, not by dock — and that button reveals it HERE, which is what `panels/activity-bar.ts`
36
- * branches on. Its record is defined beside the notification store it renders
37
- * (`panels/problems-panel.ts`) and registered from here, like every other tab of this dock.
34
+ * **Problems is one of them.** §16.3 places it here, and this dock is its only host. It has no rail
35
+ * button: its count sits in the status bar, and clicking the count runs `view.setBottomTab`. Its
36
+ * record is defined beside the notification store it renders (`panels/problems-panel.ts`) and
37
+ * registered from here, like every other tab of this dock.
38
38
  */
39
39
 
40
40
  import { render as litRender, nothing } from "lit-html";
@@ -72,10 +72,10 @@ export const BOTTOM_DOCK_SELECTOR = "#bottom-dock";
72
72
  *
73
73
  * Problems first, because it is the tab the dock opens itself for.
74
74
  *
75
- * **Diff is not among them, and its reserved id is gone.** It was held here through P4–P7 with a
75
+ * **Diff is not among them, and its reserved id is gone.** It was held here for four phases with a
76
76
  * `when: () => false`, and the comment that held it said why it should not be here: `git-diff` is
77
77
  * the `diff` EDITOR KIND (`commands/context.ts`), a pane hosts it at pane size, and folding it into
78
- * a 240px dock would be a downgrade. What it owed was a pane to open into — and P8 shipped that
78
+ * a 240px dock would be a downgrade. What it owed was a pane to open into — and §18 shipped that
79
79
  * (`pane.splitRight`, `canOpenInSecondPane`), so Source Control opens a changed file as a Diff
80
80
  * editor in the side pane. A reservation whose capability shipped elsewhere is not a reservation;
81
81
  * it is an id in `view.setBottomTab`'s enum that can only ever select a hidden tab. The dock spends
@@ -94,7 +94,7 @@ export function registerBottomPanels(): void {
94
94
  * The dock's tabs, in strip order.
95
95
  *
96
96
  * Ordered by {@link BOTTOM_TAB_IDS} rather than by registration order, because the strip's order is
97
- * a design decision (§3.2 ⑪ names it) and `shell.ts` is where a bare Bun process can read it. An id
97
+ * a design decision (§16.3 names it) and `shell.ts` is where a bare Bun process can read it. An id
98
98
  * with no record is skipped rather than throwing: the list is also the `args` enum, and a command
99
99
  * enum naming a surface that has not registered yet must be inert, not fatal.
100
100
  */
@@ -147,7 +147,7 @@ function bottomContext(): NavigatorPanelContext {
147
147
  };
148
148
  }
149
149
 
150
- /** One tab's label — the record's title, with its badge appended as §3.1 draws it ("Problems 2"). */
150
+ /** One tab's label — the record's title, with its badge appended ("Problems 2"). */
151
151
  export function bottomTabLabel(panel: PanelRecord, ctx: CommandContext): string {
152
152
  const badge = panel.badge?.(ctx) ?? null;
153
153
  return badge === null || badge === 0 || badge === "" ? panel.title : `${panel.title} ${badge}`;
@@ -219,10 +219,10 @@ function logicKey(): string | null {
219
219
  * Paint the dock, and stamp the region iff it is on screen.
220
220
  *
221
221
  * The stamp is conditional on purpose. `REGION_FOR_FOCUS.dock` has pointed at `dock.bottom` since
222
- * P3, so F6 and `regions.resolve()` will find whatever carries it — and a COLLAPSED dock is a
223
- * `display: none` box that focus must not land in and a shot must not crop. A closed dock therefore
224
- * resolves to nothing, and `view.setBottomDock { open: true }` is what makes it addressable, which
225
- * is exactly what an idempotent setter is for.
222
+ * before the dock existed, so F6 and `regions.resolve()` will find whatever carries it — and a
223
+ * COLLAPSED dock is a `display: none` box that focus must not land in and a shot must not crop. A
224
+ * closed dock therefore resolves to nothing, and `view.setBottomDock { open: true }` is what makes
225
+ * it addressable, which is exactly what an idempotent setter is for.
226
226
  */
227
227
  export function renderBottomDock(): void {
228
228
  if (!_host) {
@@ -30,8 +30,8 @@ function rowsUi(): Record<string, boolean> | null {
30
30
  *
31
31
  * The tree caps arrays at 20, objects at 30 and depth at 5, and printed "… 5 more" as inert text.
32
32
  * That is the panel telling you it has the answer and will not show it — the exact case a user
33
- * opens this panel for is the fetch that returned something unexpected at item 40. Plan §11.2:
34
- * "truncation markers gain real expand actions."
33
+ * opens this panel for is the fetch that returned something unexpected at item 40. §5.6: every
34
+ * truncation marker in the tree is a control.
35
35
  *
36
36
  * Raising a limit is remembered per marker rather than globally, so opening one long array does not
37
37
  * re-render every other one at full length, and it never lowers: a step is a step.
@@ -136,7 +136,7 @@ export function dataTypeLabel(value: unknown) {
136
136
  /* THE VALUE LIST IS GONE, AND ITS ROWS ARE THE DEFINITION ROWS — `panels/signals-panel.ts`.
137
137
  It listed every state entry with its badge and what it resolved to, one rail tab away from a
138
138
  panel listing every state entry with its badge and how it is defined: the same names twice, and
139
- you read one to understand the other. Plan §11.2 asks for "definitions + live values in one row",
139
+ you read one to understand the other. §5.6 asks for definitions and live values in one row,
140
140
  so the definition row now carries the resolved type and expands to the value tree, and what is
141
141
  left here is the tree WALK, the type label and the row-expansion record the merged rows read. */
142
142
 
@@ -369,12 +369,12 @@ export function registerDataExplorerCommands(
369
369
  *
370
370
  * `level: "document"`, because both belong to the open document.
371
371
  *
372
- * **This is where the State editor lives now.** Plan §11.2 always said so ("State panel + inline
373
- * editor → Navigator › Data"), but the two halves shipped apart: the rail button was taken away to
374
- * keep the DOCUMENT group at four, the merge was deferred, and the editor was left reachable only
375
- * by typing its name into the palette. So the one surface for declaring a state variable — or a
376
- * component property, which is a state entry with a default — became unfindable, which is a
377
- * capability lost rather than a control moved.
372
+ * **This is where the State editor lives now.** §5.6 says so (expanding a row opens the entry's
373
+ * editor), but the two halves shipped apart: the rail button was taken away to keep the DOCUMENT
374
+ * group at four, the merge was deferred, and the editor was left reachable only by typing its name
375
+ * into the palette. So the one surface for declaring a state variable — or a component property,
376
+ * which is a state entry with a default — became unfindable, which is a capability lost rather than
377
+ * a control moved.
378
378
  *
379
379
  * Defining and watching are the same task interrupted: you add an entry, then look at what it
380
380
  * resolved to. Two panels made that two panels.
@@ -205,7 +205,7 @@ let actionsState: ActionsState = { pushing: false, testResult: null, testing: nu
205
205
  /**
206
206
  * The row mounted in each host the settings machinery has handed us.
207
207
  *
208
- * Keyed by the host node, because one settings pane per stage means one host per stage (§4.1) and a
208
+ * Keyed by the host node, because one settings pane per stage means one host per stage (§18) and a
209
209
  * module-level single would make the second pane's row replace the first's.
210
210
  */
211
211
  const mounted = new Map<HTMLElement, DataActionsSurfaceHandle>();
@@ -5,13 +5,13 @@
5
5
  * It used to take over the canvas: `renderFunctionEditor` cleared `canvasWrap`, dropped every
6
6
  * canvas panel and mounted Monaco over the stage, so the page whose handler you were writing was
7
7
  * the one thing you could not see while writing it. It is a surface of the Bottom dock's **Logic**
8
- * tab now (plan §12 P8.5); `panels/formula-workspace.ts` owns that tab's record and calls the two
9
- * exports below — {@link syncFunctionEditor} from the panel's `afterRender`, and
8
+ * tab now (§16.3); `panels/formula-workspace.ts` owns that tab's record and calls the two exports
9
+ * below — {@link syncFunctionEditor} from the panel's `afterRender`, and
10
10
  * {@link closeFunctionEditor} for its Close. The container is no longer one of them: the Logic tab
11
11
  * is a Jx document (`surfaces/logic-workspace.json`) and it draws the empty
12
- * {@link CODE_HOST_SELECTOR} node itself, which is what an island is (studio-ui-guidelines.md
13
- * §9.4). The canvas keeps rendering the page underneath the dock; `canvas/canvas-render.ts` no
14
- * longer knows this surface exists.
12
+ * {@link CODE_HOST_SELECTOR} node itself: an island, as studio-ui-guidelines.md §9.4 defines one.
13
+ * The canvas keeps rendering the page underneath the dock; `canvas/canvas-render.ts` no longer
14
+ * knows this surface exists.
15
15
  *
16
16
  * **The mount is driven by the DOM, not by a render call.** A dock tab's body is re-rendered
17
17
  * whenever anything it reads changes, and a repaint will happily replace the container element out
@@ -178,9 +178,9 @@ export function syncFunctionEditor(host: HTMLElement): void {
178
178
  * work was the one that destroyed it.
179
179
  *
180
180
  * The takeover never saw this because it was torn down by exactly one thing (closing it, which
181
- * happened to be slower than the debounce). A dock tab is torn down by five, four of them new in
182
- * P8. Handling it here rather than guarding inside each callback is deliberate: a guard on "is this
183
- * still the current editor?" is passed by a timer that fires after a REMOUNT.
181
+ * happened to be slower than the debounce). A dock tab is torn down by five, four of them new with
182
+ * the pane grid (§18). Handling it here rather than guarding inside each callback is deliberate: a
183
+ * guard on "is this still the current editor?" is passed by a timer that fires after a REMOUNT.
184
184
  *
185
185
  * **But cancelling alone is the same loss with the alarm switched off.** The armed commit IS the
186
186
  * last half-second of typing; dropping it means the pre-typing body survives instead of an empty
@@ -265,15 +265,14 @@ export function mountElementsPanel(ctx: NavigatorPanelContext, host: HTMLElement
265
265
  /**
266
266
  * Contribute the Insert panel — **off the rail** (`rail: false`).
267
267
  *
268
- * §3.2 ② removes Elements from the Navigator rail because it is not a view of anything: it is an
269
- * insert palette, and a palette belongs at the caret (slash menu), on the canvas (`+`) and behind
270
- * ⌘⇧A, all of which are P3.5's Insert command family. The record survives that interval so the
271
- * surface stays reachable — `view.setActivity {tab:"insert"}`, the palette, and the screenshot
272
- * pipeline all still address it — and giving up its rail slot is what keeps the DOCUMENT group at
273
- * four.
268
+ * §5.1 keeps Insert off the Navigator rail because it is not a view of anything: it is an insert
269
+ * palette, and a palette belongs at the caret (slash menu), on the canvas (`+`) and behind ⌘⇧A, all
270
+ * of which are the Insert command family. The record survives so the surface stays reachable —
271
+ * `view.setActivity {tab:"insert"}`, the palette, and the screenshot pipeline all still address it
272
+ * — and giving up its rail slot is what keeps the DOCUMENT group at four.
274
273
  *
275
- * `level: "document"`, per principle 3's own worked example: it READS the project's component
276
- * registry and WRITES the document tree.
274
+ * `level: "document"`, per §13.2's own worked example: it READS the project's component registry
275
+ * and WRITES the document tree.
277
276
  */
278
277
  export function registerInsertPanel(): void {
279
278
  registerPanel({
@@ -68,7 +68,7 @@ export function staleSelectionMessage(): string {
68
68
  *
69
69
  * Quick Access is reached through a lazy import on purpose: this module is imported by every panel
70
70
  * in the shell, and a static edge would drag the file browser, the format host and the recents
71
- * store into all of them. P2 replaces the closure with a command id.
71
+ * store into all of them. A command id would replace the closure.
72
72
  */
73
73
  export function openPageAction(label = "Open a page…"): EmptyStateAction {
74
74
  return {
@@ -3,11 +3,11 @@
3
3
  * The Logic tab — everything about how this element BEHAVES. The FLOW behind the `logic-panel`
4
4
  * surface.
5
5
  *
6
- * Plan §6.5 re-split the inspector by task rather than by data type, and this is the tab that
7
- * gained by it. Wiring a `$switch`, wiring a repeater to a collection and wiring a click handler
8
- * are one job; they were three, split across two tabs, because a `$switch` is stored as a property
9
- * and a click handler is stored as a property-shaped function, and the old split followed the
10
- * storage. So Logic is now:
6
+ * The inspector is split by task rather than by data type (§6), and this is the tab that gained by
7
+ * it. Wiring a `$switch`, wiring a repeater to a collection and wiring a click handler are one job;
8
+ * they were three, split across two tabs, because a `$switch` is stored as a property and a click
9
+ * handler is stored as a property-shaped function, and the old split followed the storage. So Logic
10
+ * is now:
11
11
  *
12
12
  * - **Repeating list** — the `$prototype: "Array"` node's items / filter / sort, and its template.
13
13
  * - **Condition** — the `$switch` expression and its cases.
@@ -28,8 +28,9 @@
28
28
  * Three things the conversion settled, and each was a defect rather than a translation:
29
29
  *
30
30
  * - **A binding had two controls that did the same thing.** The provenance chip cleared the key and
31
- * the trash button beside it cleared the same key. §12.5 calls a second list of actions a defect;
32
- * there is one control now, and it carries the dot that says whether the selection agrees.
31
+ * the trash button beside it cleared the same key. studio-ui-guidelines.md §12.5 calls a second
32
+ * list of actions a defect; there is one control now, and it carries the dot that says whether
33
+ * the selection agrees.
33
34
  * - **The sections would not stay shut.** Repeating list, Condition and Events were rendered with a
34
35
  * hard-coded `open`, so collapsing one lasted until the next repaint. They persist through
35
36
  * `inspectorSections` like every other section in the dock.
@@ -114,9 +115,9 @@ import type {
114
115
  * The events worth SUGGESTING — not the events an element may have.
115
116
  *
116
117
  * These ten were a closed `sp-picker`, so `ondragover`, `onpointerdown`, `onwheel`, `onpaste` and
117
- * every custom event a component emits were unbindable from the Inspector: the plan's §6.5 asks for
118
- * "a free-form combobox instead of a hard-coded list of ten". The list is still ten, and it is a
119
- * list of SUGGESTIONS now — the menu's last row asks for any other name.
118
+ * every custom event a component emits were unbindable from the Inspector. An event name is typed,
119
+ * not picked (§6.1): the list is still ten, and it is a list of SUGGESTIONS now — the menu's last
120
+ * row asks for any other name.
120
121
  */
121
122
  export const EVENT_NAMES = [
122
123
  "onclick",
@@ -159,7 +160,7 @@ function seedForHandlerMode(mode: SlotMode, functionDefs: [string, unknown][]):
159
160
  // ─── The Mixed contract ──────────────────────────────────────────────────────
160
161
 
161
162
  /**
162
- * The Logic tab's Mixed contract (§6.5), stated once because it is a judgement, not a mechanism.
163
+ * The Logic tab's Mixed contract (§6.7), stated once because it is a judgement, not a mechanism.
163
164
  *
164
165
  * Wiring splits in two, and a multi-selection treats the halves differently:
165
166
  *
@@ -917,7 +918,7 @@ function watch(): void {
917
918
 
918
919
  // ─── The menus ───────────────────────────────────────────────────────────────
919
920
 
920
- /** The rung picker for a bindable row: every source this position permits, one action away (§6.3). */
921
+ /** The rung picker for a bindable row: every source this position permits, one action away (§6.6). */
921
922
  function openSourceMenu(key: string, anchor: HTMLElement): void {
922
923
  const plan = plans.fields.get(key);
923
924
  if (!plan || !canMove(plan.mode, plan.offered)) {
@@ -1,15 +1,15 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
- * ⑪ · Logic — the flow behind the Bottom dock's Logic tab.
3
+ * Logic — the flow behind the Bottom dock's Logic tab.
4
4
  *
5
5
  * **What changed, and why it is the whole point.** Both of these surfaces used to TAKE OVER the
6
6
  * canvas: `TabUi.editingFormula` (this file) and `TabUi.editingFunction` (`panels/editors.ts`) each
7
7
  * cleared `canvasWrap`, dropped every canvas panel and drew themselves over the stage. So the one
8
8
  * artefact whose values you are authoring — the page — was the one thing you could not see while
9
9
  * authoring them, and the workspace's own data rail existed to paper over it: a frozen snapshot of
10
- * a scope, shown because the live thing had just been unmounted. Plan §12 P8.5: "no editor hides
11
- * the page it computes." They are a **tab of the Bottom dock** now (§3.2 ⑪), which sits under the
12
- * pane grid, so the page renders beside the formula and keeps rendering while you edit it.
10
+ * a scope, shown because the live thing had just been unmounted. No editor may hide the page it
11
+ * computes (§16.3). They are a **tab of the Bottom dock** now, which sits under the pane grid, so
12
+ * the page renders beside the formula and keeps rendering while you edit it.
13
13
  *
14
14
  * **A dock tab is not a reparented takeover.** The surface has to work at dock height, so the
15
15
  * header is one row, the chip pipeline and the result are single lines, and the data rail is a
@@ -93,7 +93,10 @@ export type LogicTarget =
93
93
  | { surface: "function"; editing: FunctionEditDef }
94
94
  | { surface: "formula"; editing: FormulaEditDef };
95
95
 
96
- /** The sentence the tab shows with nothing open in it — what the region is FOR (§11.1). */
96
+ /**
97
+ * The sentence the tab shows with nothing open in it — what the region is FOR
98
+ * (studio-ui-guidelines.md §11.1).
99
+ */
97
100
  const NOTHING_OPEN = "Open a formula or a function to edit it here, beside the page it computes.";
98
101
 
99
102
  /** The target names a document position that holds no expression: say so, keep the header. */
@@ -128,7 +128,10 @@ export interface FmRowView {
128
128
  label: string;
129
129
  /** Which control the row draws. */
130
130
  kind: "text" | "number" | "boolean" | "select" | "media";
131
- /** Whether the value is set on this document — §4.2's dot, and the row's only clear affordance. */
131
+ /**
132
+ * Whether the value is set on this document — studio-ui-guidelines.md §4.2's dot, and the row's
133
+ * only clear affordance.
134
+ */
132
135
  isSet: boolean;
133
136
  /** The text, number or chosen value, always as a string. Empty for a boolean row. */
134
137
  value: string;
@@ -1,25 +1,30 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
- * The Document Header card (§3.2 ⑧) — the artefact's own header, drawn IN the stage.
3
+ * The Document Header card — the artefact's own header, drawn IN the stage.
4
4
  *
5
5
  * It replaces the old "Properties" bar, which was a fourth full-width band that **appeared and
6
6
  * vanished as a side effect of the canvas mode** with no control to summon it, and which showed
7
7
  * nothing at all unless `findContentTypeSchema` matched the document to a content collection — so
8
8
  * it never appeared on the default home page, the one document every new author opens first.
9
9
  *
10
- * Three gates are gone, and each was a lie about what the card is for:
10
+ * Two gates are gone, and each was a lie about what the card is for:
11
11
  *
12
12
  * - The **collection gate** (`if (!fieldSet?.collection)`) — a page's `title` is frontmatter whether
13
13
  * or not a collection schema describes it;
14
- * - The **mode gate** (`getCanvasMode() === "edit"`) — the header is part of the document, not a view
15
- * of it, so switching to Design must not delete it;
16
14
  * - The **document-mode gate** (`doc.mode === "content"`) — a JSON page carries `title` and `$head`
17
15
  * directly on the root node, and it has a header for exactly the same reason.
18
16
  *
19
- * What it renders instead: **any** document with frontmatter or `$head`, in every named layout and
20
- * in both authoring views of the stage — Title, Route, the layout picker, the
21
- * schema-and-frontmatter field list, the door to Search appearance and a "Raw head tags"
22
- * disclosure. `hasDocumentHeader` is the whole predicate, and it is a fact about the DOCUMENT.
17
+ * What it renders instead: **any** document with frontmatter or `$head`, in every named layout —
18
+ * Title, Route, the layout picker, the schema-and-frontmatter field list, the door to Search
19
+ * appearance and a "Raw head tags" disclosure. `hasDocumentHeader` is this module's whole
20
+ * predicate, and it is a fact about the DOCUMENT.
21
+ *
22
+ * **The canvas mode is the STAGE's question, and this module still takes none.** The stage draws a
23
+ * host for the card in Edit only (`wantsDocHeader` in `canvas/canvas-render.ts`): Design gives its
24
+ * artboards the whole pane, and the Navigator's Page panel carries the same fields in every mode,
25
+ * so nothing is out of reach in either. The old mode gate lived HERE, as a `getCanvasMode()` check
26
+ * the card ran to decide whether to exist; the decision now has one owner, the frame that draws the
27
+ * page, and this module draws into whatever host it is handed.
23
28
  *
24
29
  * **One reserved-key policy, one `collectFmFields` call.** The two field sets this card merges used
25
30
  * to disagree: this module passed an empty reserved set and `head-panel.ts` passed `{title}`, so
@@ -29,7 +34,8 @@
29
34
  * **The card has no host of its own.** `#frontmatter-panel` — the grid row, the `hidden` div, the
30
35
  * `frontmatterPanelEl` ref and the 40vh cap that came with them — is deleted. The STAGE renders the
31
36
  * host now ({@link attachDocumentHeaderHost}, called from the stage document's `onNodeCreated` in
32
- * `canvas/canvas-render.ts`), so the card sits inside the artefact rather than in a band above it.
37
+ * `canvas/canvas-render.ts`), so the card is docked above the page, as wide as the pane, rather
38
+ * than in a band the shell drew above every stage.
33
39
  *
34
40
  * **The card is a Jx document now** (`src/surfaces/doc-header.json`), and this module is the flow
35
41
  * behind it: it decides which document a pane's card is drawn for, which rows that document has,
@@ -55,7 +61,7 @@
55
61
  * ids behind a `#/content/<type>` reference are a read (`ui/form-controls.ts`), so the card draws
56
62
  * its own control for each and calls the owner for the part that is not markup. Neither module's
57
63
  * lit template is interpolated here — a document and a lit template cannot share a container, and
58
- * §9.4 forbids the mix outright.
64
+ * studio-ui-guidelines.md §9.4 forbids the mix outright.
59
65
  *
60
66
  * @docs studio/editing/frontmatter
61
67
  */
@@ -170,8 +176,8 @@ export function attachDocumentHeaderHost(paneId: string, el: HTMLElement | null)
170
176
  /* There is no `documentHeaderHost` getter any more, and its absence is the point.
171
177
  It existed for ONE caller: the stage's lit `ref`, which was told about a removal WITHOUT being
172
178
  told which node had gone, so it had to read the host back and ask whether it was still connected
173
- before deciding the report was about the host it held. `surfaces/canvas-stage.json` states both
174
- placements as a view, so a frame that draws no card simply announces none and `renderCanvasImpl`
179
+ before deciding the report was about the host it held. `surfaces/canvas-stage.json` states the
180
+ card's slot as a view, so a frame that draws no card simply announces none and `renderCanvasImpl`
175
181
  releases the slot in one place — there is nothing left to settle after the fact, and a getter
176
182
  whose only reader is gone is a fact about the module nobody is entitled to. */
177
183
 
@@ -360,12 +366,6 @@ function viewFor(tab: Tab, paneId: string, card: HeaderCard): DocHeaderView {
360
366
  return {
361
367
  collection: collection ? collection.name : "Document",
362
368
  hasRoute: route !== null,
363
- /* The stage's two placements, read off the host it handed over. In Edit the card is a block of
364
- the document's own column; in Design it is pinned above a pan/zoom surface at 1:1, and only
365
- that one wants the band's edge rather than the card's. `surfaces/canvas-stage.json` says the
366
- same thing from the STAGE's side, which a document's own scoped style block cannot answer —
367
- and it says it on `data-placement` rather than on a class, because the stage emits none. */
368
- placement: card.el.dataset["placement"] === "pinned" ? "pinned" : "in-column",
369
369
  rawEntries: raw,
370
370
  rawOpen: _rawOpen.has(tab.id),
371
371
  rawState: raw.length === 0 ? "empty" : "list",
@@ -23,8 +23,8 @@
23
23
  * light dismissal and Escape, so both the markup and the flag go.
24
24
  *
25
25
  * The third is the empty states. A document cannot call a lit helper, so the three this panel used
26
- * to render are drawn in the document — under the same §11 copy rules, and, for the two that offer
27
- * buttons, with the buttons still real. This was the last caller that passed
26
+ * to render are drawn in the document — under the same studio-ui-guidelines.md §11 copy rules, and,
27
+ * for the two that offer buttons, with the buttons still real. This was the last caller that passed
28
28
  * `EmptyStateAction.icon`, a `TemplateResult` of `sp-icon-*`, and the field went with it.
29
29
  *
30
30
  * @docs studio/publish/source-control
@@ -412,9 +412,9 @@ let _deps: GitPanelDeps = {};
412
412
  *
413
413
  * A `<select>` always holds one of its options, and picking "New branch…" must put the control back
414
414
  * on the current branch when the dialog is dismissed. A document's binding only writes when the
415
- * SCOPE MOVES (guidelines §9.3), so writing the current branch over a scope that already said it
416
- * would be a no-op and the control would keep saying "New branch…". Announcing what the reader
417
- * actually chose first is what makes putting it back a change.
415
+ * SCOPE MOVES (studio-ui-guidelines.md §9.3), so writing the current branch over a scope that
416
+ * already said it would be a no-op and the control would keep saying "New branch…". Announcing what
417
+ * the reader actually chose first is what makes putting it back a change.
418
418
  */
419
419
  let _branchOverride: string | null = null;
420
420
 
@@ -700,8 +700,9 @@ async function discardFile(path: string): Promise<void> {
700
700
  * The split button's second half.
701
701
  *
702
702
  * The kit menu, not a `<div>` of this panel's own: `openMenu()` owns the popover, the roving focus,
703
- * the light dismissal and Escape, and it is the answer this shell already settled on (§8.4). One
704
- * row, because there is one thing "Commit and sync" can do differently.
703
+ * the light dismissal and Escape, and it is the answer this shell already settled on
704
+ * (studio-ui-guidelines.md §8.4). One row, because there is one thing "Commit and sync" can do
705
+ * differently.
705
706
  */
706
707
  function openCommitMenu(anchor: HTMLElement): void {
707
708
  /* Lazily imported for the reason `panels/problems-panel.ts` and `panels/empty-state.ts` already
@@ -978,9 +979,10 @@ export function sourceControlCommands(): AnyCommand[] {
978
979
  // `when` already asked about the project; an `enablement` that re-asks is the same rule
979
980
  // Written twice, and the two places drift.
980
981
  enablement: (ctx) => !ctx.project.isRepo,
981
- /* No `aiTool`, by §12.4's third deletion rule: outside the tree, irreversible, and the model
982
- has no read to judge by. The git family is reconsidered together when `git.commit` becomes
983
- a record — without it the agent could not ship its own edits anyway. */
982
+ /* No `aiTool`, by studio-ui-guidelines.md §12.4's third deletion rule: outside the tree,
983
+ irreversible, and the model has no read to judge by. The git family is reconsidered
984
+ together when `git.commit` becomes a record — without it the agent could not ship its own
985
+ edits anyway. */
984
986
  run: async () => {
985
987
  await initRepository();
986
988
  },
@@ -1003,8 +1005,8 @@ export function sourceControlCommands(): AnyCommand[] {
1003
1005
  requires: "a project tracked by git",
1004
1006
  when: (ctx) => ctx.project.open,
1005
1007
  enablement: (ctx) => ctx.project.isRepo,
1006
- /* No `aiTool`, by §12.4's third deletion rule: it creates a repository on the person's
1007
- account. Same family as `git.init`. */
1008
+ /* No `aiTool`, by studio-ui-guidelines.md §12.4's third deletion rule: it creates a
1009
+ repository on the person's account. Same family as `git.init`. */
1008
1010
  run: async () => {
1009
1011
  await createGithubRepository({ projectName: projectState?.name || "my-project" });
1010
1012
  },
@@ -1019,7 +1021,8 @@ export function sourceControlCommands(): AnyCommand[] {
1019
1021
  requires: "a project tracked by git",
1020
1022
  when: (ctx) => ctx.project.open,
1021
1023
  enablement: (ctx) => ctx.project.isRepo,
1022
- /* No `aiTool`, by §12.4's third deletion rule. Same family as `git.init`. */
1024
+ /* No `aiTool`, by studio-ui-guidelines.md §12.4's third deletion rule. Same family as
1025
+ `git.init`. */
1023
1026
  run: async () => {
1024
1027
  await pushCurrentBranch();
1025
1028
  },
@@ -1073,6 +1076,9 @@ export function registerGitPanel(): void {
1073
1076
  registerPanel({
1074
1077
  id: "git",
1075
1078
  title: "Source Control",
1079
+ /* The full title is 71px against the rail's 48px label box. The header, the tooltip and the
1080
+ accessible name keep it; only the words under the glyph shorten. */
1081
+ railLabel: "Source",
1076
1082
  level: "project",
1077
1083
  dock: "navigator",
1078
1084
  // A KEY into the kit's icon manifest, not a tag: this one resolves to
@@ -480,8 +480,8 @@ export interface SeoField extends ResolvedHeadField {
480
480
  * Character budgets, in the only role a number is allowed here: a counter's reference line.
481
481
  *
482
482
  * There is deliberately no score. A single figure out of a hundred aggregates unrelated facts into
483
- * a verdict, and the verdict is what gets optimised (plan §14). A count beside a limit says the
484
- * same thing without pretending to rank it.
483
+ * a verdict, and the verdict is what gets optimised (§16.6). A count beside a limit says the same
484
+ * thing without pretending to rank it.
485
485
  */
486
486
  export const SEO_LIMITS: Readonly<Record<string, number>> = {
487
487
  description: 160,
@@ -589,7 +589,7 @@ function hasTitleEntry(layers: HeadLayers): boolean {
589
589
  *
590
590
  * Every one of them states a consequence rather than a grade, and every one is checkable against
591
591
  * `head-merger.ts`. "Missing" is decided on the MERGED value, so a page that inherits a description
592
- * from the site is never told it has none — the defect §9.2 names by name.
592
+ * from the site is never told it has none — the defect site-architecture.md §8.6 names by name.
593
593
  *
594
594
  * @param {SeoPreview} preview — `warnings` is ignored; this computes it.
595
595
  * @param {HeadLayers} layers
@@ -875,8 +875,8 @@ export function buildHeadDoc(doc: JxMutableNode, fm: Record<string, unknown>): J
875
875
  * mutation it makes — Title, Clear title, the Layout picker — as does Search appearance, which is
876
876
  * where the head fields went and which takes its tab the same way. The card is drawn per pane, so
877
877
  * on a markdown page the card in one pane retitled the document in the other. The comment beside
878
- * the card's JSON branch has claimed since P8 that this was fixed; the fix reached the JSON branch
879
- * only, and this is the half that was left.
878
+ * the card's JSON branch has claimed since the pane grid landed that this was fixed; the fix
879
+ * reached the JSON branch only, and this is the half that was left.
880
880
  *
881
881
  * @param {Tab | null} tab The document to commit into.
882
882
  * @param {() => void} rerender
@@ -1174,8 +1174,8 @@ function customEntries(head: JxHeadEntry[]): PageTagRow[] {
1174
1174
  * Everything the panel says about one document, and the commit table behind it.
1175
1175
  *
1176
1176
  * `activeTab.value` is read HERE and nowhere below it: the Navigator's Page panel is an app-level
1177
- * surface that shows the focused document by definition (§3.2), and spelling that out once at the
1178
- * top is what lets every helper under it take a tab instead of asking for one.
1177
+ * surface that shows the focused document by definition, and spelling that out once at the top is
1178
+ * what lets every helper under it take a tab instead of asking for one.
1179
1179
  */
1180
1180
  function view(ctx: PagePanelContext): PagePanelView {
1181
1181
  _commits.clear();
@@ -1454,9 +1454,8 @@ export function renderHeadTemplate(_against: PagePanelContext): typeof nothing {
1454
1454
  * Contribute the Page panel.
1455
1455
  *
1456
1456
  * `level: "document"` — title, description, social card and custom `$head` entries are the open
1457
- * document's. The id is `page` now: "head" named an HTML element, and §3.2's DOCUMENT group calls
1458
- * the surface Page. P3.10 moves these fields into the in-stage Document Header card; until then the
1459
- * record is what keeps the surface addressable under one name.
1457
+ * document's. The id is `page` now: "head" named an HTML element, and §5.1's Document group calls
1458
+ * the surface Page. The record is what keeps the surface addressable under one name.
1460
1459
  */
1461
1460
  export function registerPagePanel(): void {
1462
1461
  registerPanel({
@@ -96,7 +96,8 @@ export interface ParityRow {
96
96
  }
97
97
 
98
98
  /**
99
- * The directories a translation can live in — the two layouts §13 defines, and nothing else.
99
+ * The directories a translation can live in — the two layouts site-architecture.md §13 defines, and
100
+ * nothing else.
100
101
  *
101
102
  * Not `projectState.projectDirs`: `layouts/` and `components/` are shared by every locale and
102
103
  * `public/` is not addressable per language, so scanning them would fill the grid with rows whose
@@ -239,9 +240,10 @@ export function parityRows(
239
240
  const byKey = new Map<string, Map<string, LibraryFile>>();
240
241
  /*
241
242
  * A document's own `$translationKey` overrides the one its path implies, exactly as it does in
242
- * the build (§13.5) — which is what makes a localized slug one row instead of two half-empty
243
- * ones. Prefixed with the directory the derivation would have produced, so the two spellings meet:
244
- * a declared key is route-shaped (`about`) and this grid is file-shaped (`pages/about.json`).
243
+ * the build (site-architecture.md §13.5) — which is what makes a localized slug one row instead
244
+ * of two half-empty ones. Prefixed with the directory the derivation would have produced, so the
245
+ * two spellings meet: a declared key is route-shaped (`about`) and this grid is file-shaped
246
+ * (`pages/about.json`).
245
247
  */
246
248
  /* Every key the paths alone produce, so a declared one can be matched against a real file rather
247
249
  than against a spelling. */
@@ -65,7 +65,7 @@ export type { ElementsEntry } from "../files/elements";
65
65
  /* `componentSpecifier` and `isComponentEnabled` are `files/elements.ts`'s `npmSpecifier` and
66
66
  `hasElement`. They lived here and answered only for the two checkboxes in this file; the picker
67
67
  below and the canvas drop each asked the question their own way and got different answers
68
- (plan §11.2). One rule, four call sites. */
68
+ (§9.1.3). One rule, four call sites. */
69
69
 
70
70
  // ─── The panel's own state ───────────────────────────────────────────────────
71
71