@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
@@ -5,23 +5,20 @@
5
5
  * Its predecessor (`settings-modal.ts`) was an `inset: 40px` overlay with a scrim, which meant that
6
6
  * while you tuned a design token that pushes live to the canvas, the canvas was behind the thing
7
7
  * you were tuning it in, ⌘S/⌘Z/⌘P were suspended, and "Open Data Grid" opened a tab you could not
8
- * see. Plan §9.3 replaces it with a document in the pane whose sections are INNER NAV: Overview ·
9
- * Contexts · Site head · CSS Variables · Definitions · Content types · Packages · Extensions ·
10
- * Deploy · Raw JSON.
8
+ * see. §17.1 replaces it with a document in the pane whose sections are INNER NAV, and lists them.
11
9
  *
12
- * **The document is the `project.json` tab.** P6.1 made `project.json` a real Tab under the
13
- * transaction log with one write chokepoint (`tabs/project-config.ts`); this module opens that same
14
- * tab — same id, same document object — in the `settings` canvas mode. So the settings form, the
10
+ * **The document is the `project.json` tab.** `project.json` is a real Tab under the transaction
11
+ * log with one write chokepoint (`tabs/project-config.ts`, §17.1); this module opens that same tab
12
+ * — same id, same document object — in the `settings` canvas mode. So the settings form, the
15
13
  * Project Styles catalogue and the raw JSON are three editors over ONE document, and undo, the
16
14
  * dirty flag and ⌘S are the ordinary document verbs rather than three bespoke ones. That is the
17
- * whole of P6.1's disclosed residual ("⌘Z reaches config history only when the `project.json` tab
18
- * is focused"): the settings surface now IS that tab.
15
+ * whole of the residual the shell redesign's configuration phase disclosed ("⌘Z reaches config
16
+ * history only when the `project.json` tab is focused"): the settings surface now IS that tab.
19
17
  *
20
- * **`settings.open` did not change what it means.** §13.7 makes this phase's deliverable a
21
- * near-zero manifest diff: the command still means "reach project settings, optionally at a named
22
- * section", its args schema still declares `section`, and every shot step that names it is
23
- * untouched. What changed is the `run` — a Tab instead of a modal — and the frame the seven region
24
- * crops are taken in.
18
+ * **`settings.open` did not change what it means.** The deliverable was a near-zero manifest diff:
19
+ * the command still means "reach project settings, optionally at a named section", its args schema
20
+ * still declares `section`, and every shot step that names it is untouched. What changed is the
21
+ * `run` — a Tab instead of a modal — and the frame the seven region crops are taken in.
25
22
  *
26
23
  * @docs studio/projects/settings
27
24
  */
@@ -92,8 +89,8 @@ registerSettingsSection({
92
89
  * Contexts sits directly under Overview because it is the project's second identity: Overview says
93
90
  * what the site IS, Contexts says what it is rendered UNDER. It is a definition site only — the
94
91
  * pane context bar selects among what is defined here, and its "Manage contexts…" footer names this
95
- * key (plan §4.2, §2 principle 5). P6.3 is a RE-HOST: the section shipped in P4 through this same
96
- * registry and moves into the document's inner nav without its renderer being touched.
92
+ * key (§6.2). It is a RE-HOST: the section shipped earlier through this same registry and moved
93
+ * into the document's inner nav without its renderer being touched.
97
94
  */
98
95
  registerSettingsSection({
99
96
  icon: "browser",
@@ -124,10 +121,9 @@ registerSettingsSection({
124
121
  render: renderLocalesSection,
125
122
  });
126
123
  /*
127
- * CSS Variables is the one section §12 P6.2 does not list, and it stays until P6.4 lands the
128
- * Project Styles document that is to absorb it. Deleting it here would take the project's design
129
- * tokens off every surface for the length of one phase — and `css-variables-shot` addresses this
130
- * key by name.
124
+ * CSS Variables was the one section the shell redesign's configuration phase did not list, and it
125
+ * stayed so that the project's design tokens never left every surface at once; §17.1 lists it now,
126
+ * and `css-variables-shot` addresses this key by name.
131
127
  */
132
128
  registerSettingsSection({
133
129
  icon: "paint-brush",
@@ -288,8 +284,8 @@ export async function openProjectSettings(section?: string): Promise<void> {
288
284
  await syncExtensionSettingsSections();
289
285
  } catch (error) {
290
286
  /* Contributed sections are optional — the built-ins render regardless — but a contribution that
291
- will not load is a broken extension, and §7.2 says a thing that must be fixed and is about a
292
- named file is a Problem rather than a toast that erases itself. */
287
+ will not load is a broken extension, and §17.1 files a section that fails to load as a
288
+ Problem rather than a toast that erases itself. */
293
289
  notify.warn(`Could not load extension settings sections — ${errorMessage(error)}`, {
294
290
  key: "settings:sections",
295
291
  path: PROJECT_CONFIG_PATH,
@@ -313,11 +309,11 @@ export async function settingsSectionsReady(): Promise<void> {
313
309
  *
314
310
  * **This one record replaces four manifest verbs**: `openSettings`, `openSettings {section}`,
315
311
  * `settings.setSection` and the five `input: type` steps that clicked an entry row by region id.
316
- * The third was refused outright by plan §13.3 because its press-shim mirrored the section
317
- * registry's LABELS in a hand-kept map; the fourth was raw input standing in for a verb that did
318
- * not exist ("`settings.selectEntry` has no command record", `until: "P6.2"`). Sections have KEYS
319
- * and map-layout sections have ENTRY keys; this names both, so the manifest's input-step budget
320
- * falls by five and its unstable budget by five without one `settings.open` step changing.
312
+ * The third was refused outright by §13.5 because its press-shim mirrored the section registry's
313
+ * LABELS in a hand-kept map; the fourth was raw input standing in for a verb that did not exist
314
+ * ("`settings.selectEntry` has no command record"). Sections have KEYS and map-layout sections have
315
+ * ENTRY keys; this names both, so the manifest's input-step budget falls by five and its unstable
316
+ * budget by five without one `settings.open` step changing.
321
317
  *
322
318
  * The validation is deliberately asynchronous. Extension-contributed sections (`connections`,
323
319
  * `data`, `content`) register a tick after the document opens, so refusing synchronously would
@@ -348,22 +344,22 @@ export function settingsCommands(): AnyCommand[] {
348
344
  category: "Project",
349
345
  id: "settings.open",
350
346
  level: "project",
351
- // ⌘⇧, — the other half of §5.3's `⌘, / ⌘⇧,` pair. `app.preferences` shipped with its chord
347
+ // ⌘⇧, — the other half of §15's `⌘, / ⌘⇧,` pair. `app.preferences` shipped with its chord
352
348
  // And this one did not, so the two halves of "settings" were a keystroke and a palette search.
353
349
  keybinding: "mod+shift+,",
354
350
  menus: ["commandbar/overflow", "settings/menu", "palette"],
355
351
  group: "7_settings",
356
352
  requires: "an open project",
357
353
  /* `enablement`, not `when`: with no project open this row is DRAWN, greyed, carrying the
358
- sentence above — §12.3's rule that a control which cannot act explains itself rather than
359
- vanishing, and the reason the palette greys unavailable commands instead of hiding them.
360
- It used to be `when`, so the rail's Settings menu held one row on the welcome screen and
361
- said nothing about the other two; "why can't I" had no answer anywhere. The gate itself is
362
- unchanged — `enabledWith` still refuses, so `registry.run` and the assistant's tool still
363
- throw `CommandUnavailableError` exactly as before. */
354
+ sentence above — `studio-ui-guidelines.md` §12.3's rule that a control which cannot act
355
+ explains itself rather than vanishing, and the reason the palette greys unavailable
356
+ commands instead of hiding them. It used to be `when`, so the rail's Settings menu held one
357
+ row on the welcome screen and said nothing about the other two; "why can't I" had no answer
358
+ anywhere. The gate itself is unchanged — `enabledWith` still refuses, so `registry.run` and
359
+ the assistant's tool still throw `CommandUnavailableError` exactly as before. */
364
360
  enablement: (ctx) => ctx.project.open,
365
- /* No `aiTool`, by §12.4's first deletion rule: this opens a surface for a person; the model
366
- writes `project.json` through `write_file` and the extension verbs. */
361
+ /* No `aiTool`, by `studio-ui-guidelines.md` §12.4's first rule: this opens a surface for a
362
+ person; the model writes `project.json` through `write_file` and the extension verbs. */
367
363
  run: async (_commandCtx, args) => {
368
364
  const section = optionalStringArg("settings.open", args, "section");
369
365
  const entry = optionalStringArg("settings.open", args, "entry");
@@ -405,10 +401,10 @@ export function settingsCommands(): AnyCommand[] {
405
401
  * in for this: it is level `document` and requires an open one, so from a cold workspace there
406
402
  * is nothing to re-mode.
407
403
  *
408
- * It is a peer of `settings.open` and declares the same gate, byte for byte (§12.4: two verbs
409
- * over one document declare ONE availability rule). `styles.*` is the project-level plural of
410
- * the selection-level `style.*` verbs in `panels/style-panel.ts`; the ids are one letter apart
411
- * and the levels are the reason.
404
+ * It is a peer of `settings.open` and declares the same gate, byte for byte
405
+ * (`studio-ui-guidelines.md` §12.4: two verbs over one document declare ONE availability
406
+ * rule). `styles.*` is the project-level plural of the selection-level `style.*` verbs in
407
+ * `panels/style-panel.ts`; the ids are one letter apart and the levels are the reason.
412
408
  */
413
409
  {
414
410
  category: "Project",
@@ -416,13 +412,15 @@ export function settingsCommands(): AnyCommand[] {
416
412
  level: "project",
417
413
  menus: ["settings/menu", "palette"],
418
414
  /* A distinct ordinal inside the settings family, so the gear reads Settings → Styles.
419
- §12.3's lever is `group`, never a per-menu sort; `styles.open` is not in the ⬢ menu, so
420
- nothing else sees this string. */
415
+ `studio-ui-guidelines.md` §12.3's lever is `group`, never a per-menu sort; `styles.open` is
416
+ not in the ⬢ menu, so nothing else sees this string. */
421
417
  group: "7_settings_styles",
422
418
  requires: "an open project",
423
- // §12.4: two verbs over ONE document declare ONE availability rule, byte-identical.
419
+ /* `studio-ui-guidelines.md` §12.4: two verbs over ONE document declare ONE availability rule,
420
+ byte-identical. */
424
421
  enablement: (ctx) => ctx.project.open,
425
- /* No `aiTool`, by §12.4's first deletion rule: this opens a surface for a person. */
422
+ /* No `aiTool`, by `studio-ui-guidelines.md` §12.4's first rule: this opens a surface for a
423
+ person. */
426
424
  run: () => {
427
425
  showSettingsDocument(PROJECT_STYLES_VIEW);
428
426
  },
package/src/shell/tree.ts CHANGED
@@ -16,6 +16,8 @@
16
16
  import { html, render as litRender } from "lit-html";
17
17
  import type { TemplateResult } from "lit-html";
18
18
  import { mountShellSurface } from "../surfaces/shell";
19
+ import { mountBootFailureSurface } from "../surfaces/boot-failure";
20
+ import type { BootRefusal } from "../platforms/default-platform";
19
21
 
20
22
  /**
21
23
  * The four overlay layers that `ui/layers.ts` renders into, in stacking order.
@@ -83,6 +85,33 @@ export async function mountShellTree(host: ParentNode = document.body): Promise<
83
85
  litRender(overlayLayers(), root);
84
86
  }
85
87
 
88
+ /**
89
+ * Render the boot-failure screen into `host` INSTEAD of the frame.
90
+ *
91
+ * `studio.ts` calls this when no platform adapter can be had — a launcher declared or announced
92
+ * itself and registered nothing (`platforms/default-platform.ts`). The frame is not drawn under it
93
+ * or beside it: every region of the frame is a promise to open, save or create something, and the
94
+ * whole reason this screen exists is that desktop 5.0.0 to 5.1.3 made those promises from a window
95
+ * with no backend. No overlay layers either — nothing that could raise a toast or a dialog is going
96
+ * to run.
97
+ *
98
+ * It mounts into the same {@link shellRoot} the frame would have, and clears it the same way, so a
99
+ * test (or a host) that already painted a frame there is left with the screen alone.
100
+ *
101
+ * @param refusal Why the dev-server fallback was refused.
102
+ * @param host Where the screen goes. Defaults to the document body.
103
+ */
104
+ export async function mountBootFailureTree(
105
+ refusal: BootRefusal,
106
+ host: ParentNode = document.body,
107
+ ): Promise<void> {
108
+ const root = shellRoot(host);
109
+ root.textContent = "";
110
+ // @ts-expect-error -- _$litPart$ is lit's private render-part marker, not in the DOM types
111
+ delete root["_$litPart$"];
112
+ await mountBootFailureSurface(root, refusal);
113
+ }
114
+
86
115
  /**
87
116
  * The element the frame and its layers are mounted into, created once and reused.
88
117
  *
package/src/shell.ts CHANGED
@@ -56,14 +56,14 @@ export type LayoutSelection = LayoutHit;
56
56
  *
57
57
  * `"chat"` is not among them: the assistant is the Inspector's fourth TAB, not a dock, so it has no
58
58
  * column, no size, no collapse flag and no resize handle of its own — which is the whole claim of
59
- * plan §3.2 ⑨, that folding it in costs zero additional width. What selects it is
59
+ * §3.1's "no assistant column", that folding it in costs zero additional width. What selects it is
60
60
  * {@link INSPECTOR_TAB_IDS}, the same mechanism that selects Content, Style and Logic.
61
61
  *
62
- * `"bottom"` is the one that arrives with P4.2. It is a dock like the other two — a collapse flag,
63
- * a remembered size, a resize handle, a place in every {@link LayoutPreset} — and the reason
62
+ * `"bottom"` is the one the Bottom dock (§16.3) added. It is a dock like the other two — a collapse
63
+ * flag, a remembered size, a resize handle, a place in every {@link LayoutPreset} — and the reason
64
64
  * `view.toggleBottomDock` had no idempotent setter for two phases is that it was not on this
65
- * record. It sits under the PANE GRID rather than under the window (plan §3.2 ⑪), so opening it
66
- * never narrows the Navigator or the Inspector.
65
+ * record. It sits under the PANE GRID rather than under the window (§16.3), so opening it never
66
+ * narrows the Navigator or the Inspector.
67
67
  */
68
68
  export type DockId = "left" | "right" | "bottom";
69
69
 
@@ -72,10 +72,10 @@ export type DockId = "left" | "right" | "bottom";
72
72
  *
73
73
  * This is the DECLARATION `view.setActivity`'s `args` enum is built from, and it is the reason a
74
74
  * panel rename fails `scripts/check-shot-contract.ts` in the renaming PR naming both ids instead of
75
- * silently photographing the wrong panel (plan §13.5). `shell.leftTab` stays a `string` because it
76
- * is also read from persisted state written by an older build — the COMMAND is what refuses an
77
- * undeclared id, at the one door a caller comes through, and {@link migratePanelId} is what turns a
78
- * stale stored id into a current one before it gets there.
75
+ * silently photographing the wrong panel (Lane 1, `scripts/screenshots/README.md`). `shell.leftTab`
76
+ * stays a `string` because it is also read from persisted state written by an older build — the
77
+ * COMMAND is what refuses an undeclared id, at the one door a caller comes through, and
78
+ * {@link migratePanelId} is what turns a stale stored id into a current one before it gets there.
79
79
  *
80
80
  * **`"problems"` is not here, and it has no rail button either.** It is hosted in the Bottom dock,
81
81
  * so `view.setBottomTab { tab: "problems" }` is the verb that shows it and this enum would be a
@@ -119,7 +119,7 @@ const RENAMED_PANEL_IDS: Readonly<Record<string, NavigatorPanelId>> = {
119
119
  blocks: "insert",
120
120
  head: "page",
121
121
  imports: "packages",
122
- /* Not a rename — a MERGE. The State editor is part of the Data panel now (plan §11.2), so a
122
+ /* Not a rename — a MERGE. The State editor is part of the Data panel now (§5.6), so a
123
123
  stored `leftTab: "state"` names a real place and lands on it, rather than returning `null` and
124
124
  booting into the default the way `problems` does. Defining a value and watching it resolve are
125
125
  one task; they were two panels. */
@@ -160,10 +160,11 @@ export function requireNavigatorPanelId(value: string, source: string): Navigato
160
160
  * {@link DEFAULT_PANEL_ID}, and a test can tell "I stored junk" from "I stored `layers`".
161
161
  *
162
162
  * `"problems"` is the one id that returns `null` because it MOVED rather than because it was junk:
163
- * a build before §7.2's correction could persist `leftTab: "problems"`, and the Navigator can no
164
- * longer show it. There is no alias to add — Problems is not a Navigator panel under any name — so
165
- * the shell boots into {@link DEFAULT_PANEL_ID} and the Bottom dock keeps its own `bottomTab`,
166
- * which already defaults to Problems. This is exactly the wedge this function exists to prevent.
163
+ * a build from before Problems moved to the Bottom dock (§16.3) could persist `leftTab:
164
+ * "problems"`, and the Navigator can no longer show it. There is no alias to add — Problems is not
165
+ * a Navigator panel under any name — so the shell boots into {@link DEFAULT_PANEL_ID} and the
166
+ * Bottom dock keeps its own `bottomTab`, which already defaults to Problems. This is exactly the
167
+ * wedge this function exists to prevent.
167
168
  */
168
169
  export function migratePanelId(stored: unknown): NavigatorPanelId | null {
169
170
  if (typeof stored !== "string") {
@@ -184,8 +185,8 @@ export function migratePanelId(stored: unknown): NavigatorPanelId | null {
184
185
  * (`view.setAssistant`) precisely because the assistant was somewhere else; it survives as the
185
186
  * dock-toggle spelling of "show me the assistant", but it now writes the same field as the others.
186
187
  *
187
- * The ORDER is §3.2 ⑨'s — Content · Style · Logic · Assistant — which is the order ⌘⇧1–4 follow.
188
- * The human titles live in `commands/defaults.ts`'s `INSPECTOR_TABS` (a module with no state and no
188
+ * The ORDER is §6's — Content · Style · Logic · Assistant — which is the order ⌘⇧1–4 follow. The
189
+ * human titles live in `commands/defaults.ts`'s `INSPECTOR_TABS` (a module with no state and no
189
190
  * DOM, so the CI checks can load it); `tests/right-panel.test.ts` asserts the two agree, the same
190
191
  * way `tests/panel-registry.test.ts` does for the rail.
191
192
  */
@@ -202,12 +203,12 @@ export function isInspectorTabId(value: unknown): value is InspectorTabId {
202
203
  }
203
204
 
204
205
  /**
205
- * The Bottom dock's tab ids, in strip order — plan §3.2 ⑪, at the documented cap of four.
206
+ * The Bottom dock's tab ids, in strip order — §16.3: three tabs, under the documented cap of four.
206
207
  *
207
- * **Four, not five.** `scripts/check-chrome-budget.ts` caps a dock at four tabs, and §12's P4 entry
208
- * resolves the fifth candidate explicitly: **Deploy folds into Activity**, because a deploy IS a
209
- * long operation with a log, and giving it its own tab would have bought a fifth strip item to say
210
- * what the fourth already says.
208
+ * **Deploy is not a tab.** `scripts/check-chrome-budget.ts` caps a dock at four tabs, and the shell
209
+ * redesign's feedback phase resolved that candidate explicitly: **Deploy folds into Activity**,
210
+ * because a deploy IS a long operation with a log, and giving it its own tab would have bought a
211
+ * strip item to say what Activity already says.
211
212
  *
212
213
  * Declared here, beside {@link NAVIGATOR_PANEL_IDS} and {@link INSPECTOR_TAB_IDS} and for the same
213
214
  * reason: `view.setBottomTab`'s `args` enum is built from it, and `commands/app-commands.ts` must
@@ -291,24 +292,25 @@ export interface ShellStylebook {
291
292
  }
292
293
 
293
294
  /**
294
- * A named arrangement of the shell — plan §3.2 ①b.
295
+ * A named arrangement of the shell — a layout tab (`docs/studio/interface.md`, "Command Bar").
295
296
  *
296
297
  * A layout is a TUPLE, not a mode: which Navigator panel is showing, whether each dock is open and
297
298
  * how wide, and which Inspector tab is selected. Picking one reconfigures; it never removes. Every
298
- * panel stays reachable by rail, chord and palette afterwards, because §13 rejects workspaces that
299
- * gate features — telling a copy editor the Style panel "is in ⌘K" hands the non-technical user the
300
- * one affordance they are least likely to reach for.
299
+ * panel stays reachable by rail, chord and palette afterwards, because workspaces that gate
300
+ * features are refused (`docs/studio/interface.md`, "Command Bar") — telling a copy editor the
301
+ * Style panel "is in ⌘K" hands the non-technical user the one affordance they are least likely to
302
+ * reach for.
301
303
  *
302
304
  * The field this replaces (`shell.layout`, a string with a declared default and NO writer) was the
303
305
  * exact failure `layoutSelection` had already been through: a record nothing sets, read by chrome
304
306
  * that therefore cannot change. Wiring it was the alternative to deleting it, and these are the
305
307
  * writers.
306
308
  *
307
- * **Editor kind is deliberately not in the tuple.** §3.2 ①b names it, but nothing in the shell can
308
- * apply it: switching a pane's editor is `studio.ts`'s `setCanvasMode`, which this module does not
309
- * have and cannot be handed without changing a bootstrap it does not own. A fourth field no writer
310
- * could honour would recreate the defect this type exists to close, so the tuple is three fields
311
- * and the fourth arrives with the pane record that can carry it.
309
+ * **Editor kind is deliberately not in the tuple.** The shell redesign's layout tuple named it, but
310
+ * nothing in the shell can apply it: switching a pane's editor is `studio.ts`'s `setCanvasMode`,
311
+ * which this module does not have and cannot be handed without changing a bootstrap it does not
312
+ * own. A fourth field no writer could honour would recreate the defect this type exists to close,
313
+ * so the tuple is three fields and the fourth arrives with the pane record that can carry it.
312
314
  */
313
315
  export interface LayoutPreset {
314
316
  /** Stable key. Built-ins use their own lowercase name; a saved layout gets a slug of its. */
@@ -362,7 +364,7 @@ export interface ShellState {
362
364
  const DOCK_STORAGE_KEY = "jx-studio-panel-widths";
363
365
 
364
366
  /**
365
- * The per-project record's key prefix — one namespaced record per project root (§4.4).
367
+ * The per-project record's key prefix — one namespaced record per project root (§14.8).
366
368
  *
367
369
  * Namespaced because a layout is an arrangement of THIS project's panels: "Ship" over a repo with
368
370
  * no git remote is not the same tuple as "Ship" over one that has one, and two projects sharing a
@@ -403,8 +405,8 @@ export const DOCK_IDS: DockId[] = ["left", "right", "bottom"];
403
405
  * The two side docks open, because the shell's whole point is that it says where you are. The
404
406
  * Bottom dock CLOSED, because it is the one dock whose contents are usually empty: a Problems list
405
407
  * with nothing in it and an Activity log with nothing running would spend 220px of the canvas — the
406
- * one region §3.2 says must never disappear — to say "nothing has gone wrong". ⌘J opens it, the
407
- * rail badge and the status bar say when it has something to show, and nothing opens it for you.
408
+ * one region §16.3 says must never disappear — to say "nothing has gone wrong". ⌘J opens it, the
409
+ * status bar says when it has something to show, and nothing opens it for you.
408
410
  */
409
411
  const DOCK_DEFAULTS: Record<DockId, DockState> = {
410
412
  bottom: { collapsed: true, size: 220 },
@@ -443,9 +445,10 @@ const DOCK_CLASS: Record<DockId, string> = {
443
445
  * The persisted shell record. Absent keys keep the declared default.
444
446
  *
445
447
  * `leftTab` rides in the same record as the dock geometry because it is remembered for the same
446
- * reason and by the same writer — one key, one shape, one `JSON.stringify`. P3.7 replaces the whole
447
- * thing with a per-project session record; until then, adding a second localStorage key would
448
- * recreate the two-writer bug this record was consolidated to fix.
448
+ * reason and by the same writer — one key, one shape, one `JSON.stringify`. The shell redesign
449
+ * planned to replace the whole thing with a per-project session record (§14.8 now holds the
450
+ * session); until then, adding a second localStorage key would recreate the two-writer bug this
451
+ * record was consolidated to fix.
449
452
  */
450
453
  interface PersistedDocks {
451
454
  left?: number;
@@ -523,7 +526,7 @@ function freshStylebook(): ShellStylebook {
523
526
  }
524
527
 
525
528
  /**
526
- * The four layouts every project starts with — §3.2 ①b's `Write · Design · Build · Ship`.
529
+ * The four layouts every project starts with — `Write · Design · Build · Ship`.
527
530
  *
528
531
  * Each is a real arrangement of surfaces that already exist, not a mode: Write puts the file set
529
532
  * beside the prose and the Inspector on Content; Design opens the Outline against the Style tab;
@@ -541,12 +544,12 @@ function builtInLayouts(): LayoutPreset[] {
541
544
  docks: {
542
545
  bottom: { collapsed: true, size: 220 },
543
546
  left: { collapsed: false, size: 240 },
544
- /* WRITE COLLAPSES THE INSPECTOR. §3.1's arithmetic is the whole point of this preset:
545
- 1600px − 56 rail − 240 navigator ≈ **1284px of page, 80%**, against Design's 974. It
546
- shipped with the Inspector open at 280px, which is Design's number and makes Write a
547
- Design with a different panel selected.
547
+ /* WRITE COLLAPSES THE INSPECTOR. The shell redesign's layout arithmetic is the whole point
548
+ of this preset: 1600px − 56 rail − 240 navigator ≈ **1284px of page, 80%**, against
549
+ Design's 974. It shipped with the Inspector open at 280px, which is Design's number and
550
+ makes Write a Design with a different panel selected.
548
551
 
549
- It does NOT re-open on selection. The plan's sentence reads "until something is
552
+ It does NOT re-open on selection. The shell redesign's sentence read "until something is
550
553
  selected", and clicking a paragraph to put a caret in it IS a selection — a dock that
551
554
  opened every time you clicked into prose would take the 80% back on the first keystroke.
552
555
  `⌘⇧1`–`⌘⇧4` expand it (`focusInspectorTab` sets `collapsed: false` before it focuses), so
@@ -584,7 +587,7 @@ function builtInLayouts(): LayoutPreset[] {
584
587
  },
585
588
  {
586
589
  // The one built-in that OPENS the Bottom dock, on Activity: shipping is a long operation
587
- // With a log, which is exactly what that tab is (§12 P4 — Deploy folds into Activity).
590
+ // With a log, which is exactly what that tab is (§16.4 — Deploy folds into Activity).
588
591
  bottomTab: "activity",
589
592
  docks: {
590
593
  bottom: { collapsed: false, size: 240 },
@@ -686,13 +689,13 @@ export function persistDocks(): void {
686
689
  }
687
690
  }
688
691
 
689
- // ─── Named layouts (§3.2 ①b) ──────────────────────────────────────────────────
692
+ // ─── Named layouts ────────────────────────────────────────────────────────────
690
693
 
691
694
  /** What a project's namespaced record holds: its named layouts, and the session it was left in. */
692
695
  interface PersistedProject {
693
696
  layouts?: unknown;
694
697
  activeLayout?: unknown;
695
- /** §4.4's session — open documents per pane, the active one, and each one's view settings. */
698
+ /** §14.8's session — open documents per pane, the active one, and each one's view settings. */
696
699
  session?: unknown;
697
700
  }
698
701
 
@@ -954,7 +957,7 @@ export function deleteLayout(id: string): void {
954
957
  }
955
958
 
956
959
  /**
957
- * Re-apply the active layout as declared — `View: Reset Layout`, always one action away (§3.2 ①b).
960
+ * Re-apply the active layout as declared — `View: Reset Layout`, always one action away.
958
961
  *
959
962
  * This is the escape hatch that makes a layout safe to drift from: drag a dock, collapse the
960
963
  * Inspector, open a different panel, and one command puts the arrangement back.
@@ -1090,7 +1093,7 @@ export function mountShell(): void {
1090
1093
  syncProjectLayouts(workspace.projectRoot);
1091
1094
  });
1092
1095
  /*
1093
- * §4.4's session, written whenever its SHAPE changes.
1096
+ * §14.8's session, written whenever its SHAPE changes.
1094
1097
  *
1095
1098
  * The reads below are the tracking list: which panes exist, what is in each strip and in what
1096
1099
  * order, which tab is active, and where the keyboard is. Every one of them is a deliberate act
@@ -1282,7 +1285,7 @@ const projectOpen = (ctx: { project: { open: boolean } }) => ctx.project.open;
1282
1285
  /**
1283
1286
  * The shell's view verbs: idempotent SETTERS, never toggles.
1284
1287
  *
1285
- * Plan §13.3 clause 3 is the whole shape of this list. `view.toggleAssistant` names a _delta_
1288
+ * §13.5's idempotence rule is the whole shape of this list. `view.toggleAssistant` names a _delta_
1286
1289
  * against state the caller cannot observe, so flipping the assistant's default silently inverted 18
1287
1290
  * screenshots and an agent calling it is guessing; `view.setAssistant { open: false }` means the
1288
1291
  * same thing whichever way the default points. The rail's own click handler keeps its
@@ -1291,7 +1294,7 @@ const projectOpen = (ctx: { project: { open: boolean } }) => ctx.project.open;
1291
1294
  *
1292
1295
  * The `args` enums are the highest-value declaration here: `view.setActivity`'s `tab` is exactly
1293
1296
  * {@link NAVIGATOR_PANEL_IDS}, so renaming a panel turns every stale manifest step red naming both
1294
- * ids, in the PR that renamed it (plan §13.5).
1297
+ * ids, in the PR that renamed it (Lane 1, `scripts/screenshots/README.md`).
1295
1298
  *
1296
1299
  * @param {ShellCommandDeps} deps
1297
1300
  * @returns {AnyCommand[]}
@@ -1310,7 +1313,8 @@ export function shellViewCommands(deps: ShellCommandDeps): AnyCommand[] {
1310
1313
  requires: "an open project",
1311
1314
  when: projectOpen,
1312
1315
  /* No `aiTool`: application-level, which `register()` refuses to project — an application verb
1313
- acts on the editor, which the model cannot see (§12.4, chrome). */
1316
+ acts on the editor, which the model cannot see (`studio-ui-guidelines.md` §12.4,
1317
+ chrome). */
1314
1318
  run: (_ctx, args) => {
1315
1319
  const tab = enumArg("view.setActivity", args, "tab", NAVIGATOR_PANEL_IDS);
1316
1320
  // The record's own `when`, asked here because `enablement` cannot see an argument — the
@@ -1379,7 +1383,8 @@ export function shellViewCommands(deps: ShellCommandDeps): AnyCommand[] {
1379
1383
  category: "View",
1380
1384
  // The idempotent half of `view.toggleBottomDock`, and the reason the toggle can exist at all:
1381
1385
  // `tests/app-commands.test.ts` fails any `toggle*` id with no `set*` beside it, and this one
1382
- // Has been listed as HANDOFF debt since P2 because the dock was not on the `shell` record.
1386
+ // Has been listed as HANDOFF debt since the shell redesign's registry phase because the
1387
+ // Dock was not on the `shell` record.
1383
1388
  // It is now, so this is a two-line `run` rather than the special case ⌘J used to need.
1384
1389
  id: "view.setBottomDock",
1385
1390
  level: "application",
@@ -1392,8 +1397,9 @@ export function shellViewCommands(deps: ShellCommandDeps): AnyCommand[] {
1392
1397
  },
1393
1398
  {
1394
1399
  // ⌘J. A gesture, not an API: a human presses it while looking at the dock, which is the
1395
- // Exemption §13.3 clause 3 grants a toggle whose state the presser can SEE. A script says
1396
- // `view.setBottomDock { open }` instead, and the test beside the registry enforces the pair.
1400
+ // Exemption §13.5's idempotence rule grants a toggle whose state the presser can SEE. A
1401
+ // Script says `view.setBottomDock { open }` instead, and the test beside the registry
1402
+ // Enforces the pair.
1397
1403
  category: "View",
1398
1404
  id: "view.toggleBottomDock",
1399
1405
  keybinding: "mod+j",
@@ -1414,7 +1420,8 @@ export function shellViewCommands(deps: ShellCommandDeps): AnyCommand[] {
1414
1420
  level: "application",
1415
1421
  menus: ["palette"],
1416
1422
  group: "4_docks",
1417
- /* No `aiTool`: application-level chrome, refused at registration (§12.4). */
1423
+ /* No `aiTool`: application-level chrome, refused at registration
1424
+ (`studio-ui-guidelines.md` §12.4). */
1418
1425
  run: (_ctx, args) => {
1419
1426
  const tab = enumArg("view.setBottomTab", args, "tab", BOTTOM_TAB_IDS);
1420
1427
  // The record's own `when`, asked here because `enablement` cannot see an argument — the
@@ -1477,7 +1484,8 @@ export function shellViewCommands(deps: ShellCommandDeps): AnyCommand[] {
1477
1484
  group: "4_layouts",
1478
1485
  requires: "an open project",
1479
1486
  when: projectOpen,
1480
- /* No `aiTool`: application-level chrome, refused at registration (§12.4). */
1487
+ /* No `aiTool`: application-level chrome, refused at registration
1488
+ (`studio-ui-guidelines.md` §12.4). */
1481
1489
  run: (_ctx, args) => {
1482
1490
  applyLayout(stringArg("view.setLayout", args, "layout"), deps);
1483
1491
  },
@@ -292,7 +292,7 @@ function fillSlots(
292
292
  * file that defines the project with no history behind them.
293
293
  *
294
294
  * **It still rejects.** `settings/general-settings.ts` and `settings/contexts-section.ts` catch the
295
- * rejection and park it on the control that caused it (§7.1's inline tier), and that is the right
295
+ * rejection and park it on the control that caused it (§16.1's inline tier), and that is the right
296
296
  * treatment for a field the author is looking at. The chokepoint ALSO files the failure as a
297
297
  * Problem, because the eight other sites reach this through `void updateSiteConfig(...)` and used
298
298
  * to drop it on the floor.
package/src/store.ts CHANGED
@@ -133,7 +133,7 @@ const _renderers = new Map<string, () => void>();
133
133
  /**
134
134
  * How many registered renderers are mid-paint right now.
135
135
  *
136
- * Condition 1 of the `probe.idle()` predicate (`services/idle.ts`, spec §13.5). A renderer is
136
+ * Condition 1 of the `probe.idle()` predicate (`services/idle.ts`, studio.md §13.5). A renderer is
137
137
  * declared `() => void`, but TypeScript happily assigns an `async` function to that type, so a
138
138
  * renderer that awaits keeps repainting long after `render()` returned. Counting the returned
139
139
  * thenable is what makes "no queued lit render" an answerable question instead of an assumption —
@@ -228,7 +228,7 @@ export function renderOnly(...names: string[]) {
228
228
  export function updateSession(
229
229
  tab: Tab | null,
230
230
  patch: {
231
- /** The whole selection SET — `[]` clears it. Widened with `session.selection` itself (§6.5). */
231
+ /** The whole selection SET — `[]` clears it. Widened with `session.selection` itself (§6.7). */
232
232
  selection?: JxPath[];
233
233
  hover?: JxPath | null;
234
234
  clipboard?: JxMutableNode | null;