@jxsuite/studio 2.0.0 → 2.1.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 (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-0hzentwq.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-0hzentwq.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-2c188n41.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-97qcgvdn.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-97qcgvdn.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-hhj92gcr.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-ygzav7z5.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-n9zmpxjg.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +23711 -35185
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +34 -9
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +270 -262
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -120
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +75 -2
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +113 -0
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qct0gt8f.js +0 -531
  363. package/dist/chunks/extension-sections-qct0gt8f.js.map +0 -12
  364. package/dist/chunks/files-02zn5y24.js +0 -50
  365. package/dist/chunks/files-02zn5y24.js.map +0 -9
  366. package/dist/chunks/git-panel-mbb0y0hz.js +0 -28
  367. package/dist/chunks/git-panel-mbb0y0hz.js.map +0 -9
  368. package/dist/chunks/layers-panel-9qekmqk1.js +0 -26
  369. package/dist/chunks/layers-panel-9qekmqk1.js.map +0 -9
  370. package/dist/chunks/settings-modal-gj0hrah4.js +0 -29
  371. package/dist/chunks/settings-modal-gj0hrah4.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  381. package/dist/chunks/studio-568nx4t5.js +0 -469
  382. package/dist/chunks/studio-568nx4t5.js.map +0 -14
  383. package/dist/chunks/studio-9smfzqhc.js +0 -19
  384. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  385. package/dist/chunks/studio-asvf0j9e.js +0 -429
  386. package/dist/chunks/studio-asvf0j9e.js.map +0 -13
  387. package/dist/chunks/studio-d77qm3pk.js +0 -3427
  388. package/dist/chunks/studio-d77qm3pk.js.map +0 -26
  389. package/dist/chunks/studio-j6gqyjf4.js +0 -1854
  390. package/dist/chunks/studio-j6gqyjf4.js.map +0 -18
  391. package/dist/chunks/studio-n9zmpxjg.js.map +0 -115
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-rq0vxb19.js +0 -3744
  394. package/dist/chunks/studio-rq0vxb19.js.map +0 -22
  395. package/dist/chunks/studio-wd6ewdvd.js +0 -853
  396. package/dist/chunks/studio-wd6ewdvd.js.map +0 -12
  397. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  398. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  399. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  400. package/dist/chunks/studio-ygzav7z5.js.map +0 -46
  401. package/dist/chunks/studio-zmy7241e.js +0 -399
  402. package/dist/chunks/studio-zmy7241e.js.map +0 -12
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-2c188n41.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-hhj92gcr.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -0,0 +1,580 @@
1
+ /**
2
+ * Defaults.ts — the first real command records.
3
+ *
4
+ * These are not examples. Each one is a capability Studio already has, written out in the form
5
+ * every surface will read it from, with the implementation taken by injection ({@link CommandDeps})
6
+ * so this module imports no state and can be loaded by a CI check in a bare Bun process. Next wave
7
+ * the bootstrap passes the real functions; nothing about the records changes.
8
+ *
9
+ * The one value import is `isSpliceablePath` — a four-token predicate over a path array, from the
10
+ * module that also enforces it inside the mutators. An enablement predicate and the mutator it
11
+ * guards disagreeing about which paths are editable is exactly how a Delete comes to be offered on
12
+ * a selection it corrupts, so the two read the same function rather than the same sentence.
13
+ *
14
+ * Two of them exist to settle arguments the current code has with itself:
15
+ *
16
+ * - `document.close` is ⌘W. Today `editor/shortcuts.ts:192` refuses to close the last tab while
17
+ * `panels/tab-strip.ts:182`'s × closes it happily. Here the chord and the × button are the same
18
+ * record, so they cannot disagree again.
19
+ * - `selection.duplicate` is "duplicate node", implemented four times today. Its `requires` string is
20
+ * what the block action bar's tooltip, the palette's grey subtitle and the agent's refusal all
21
+ * print — one sentence, three consumers.
22
+ *
23
+ * The primary Command Bar cluster is capped at five by `scripts/check-chrome-budget.ts`; four are
24
+ * spent here (Save, Undo, Redo, Open in Browser) exactly as plan §3.2 region ① specifies.
25
+ */
26
+
27
+ import { isSpliceablePath } from "../tabs/selection";
28
+
29
+ import type { AnyCommand } from "./registry";
30
+ import type { CommandContext } from "./context";
31
+
32
+ /**
33
+ * Which dock {@link CommandDeps.toggleDock} addresses.
34
+ *
35
+ * The Command Bar draws three toggles, but only two come through this verb: the Bottom dock's is
36
+ * `shell.ts`'s `view.toggleBottomDock`, which writes `shell.docks.bottom` directly now that the
37
+ * dock is on the shell record. `"bottom"` survives in the union only because
38
+ * `editor/shortcuts.ts`'s `toggleShellDock` still carries the branch that used to route ⌘J to the
39
+ * Assistant — HANDOFF: that branch is now unreachable, and it goes with this member.
40
+ */
41
+ export type DockId = "navigator" | "inspector" | "bottom";
42
+
43
+ /**
44
+ * Palette modes, echoed as a removable chip in the input (plan §5.4).
45
+ *
46
+ * The value space is the palette's namespace, declared once here so a new mode is a new member
47
+ * rather than a new widget: P4's Problems and P7's content search slot in beside these.
48
+ */
49
+ export type PaletteMode = "picker" | "files" | "commands" | "nodes" | "projects";
50
+
51
+ /**
52
+ * One panel, as the ⌘1–8 direct keys address it.
53
+ *
54
+ * Structurally the part of `panels/panel-registry.ts`'s `PanelRecord` a chord needs, declared here
55
+ * rather than imported so this module keeps its one load-bearing property: it imports no state and
56
+ * no DOM, which is what lets the three CI checks load the command set in a bare Bun process. The
57
+ * ROSTER arrives by injection ({@link CommandDeps.panelRoster}) from the panel registry, so there
58
+ * is still exactly one place a panel is named.
59
+ */
60
+ export interface RailPanel {
61
+ /** The panel's registry id — what `deps.focusPanel` is handed. */
62
+ id: string;
63
+ /** The panel's human name, which is also the command's title after "Show ". */
64
+ title: string;
65
+ /** `false` for a panel with no rail button — reachable by name, not by number. */
66
+ rail?: boolean;
67
+ /** The panel's own visibility predicate, composed into the command's. */
68
+ when?: (ctx: CommandContext) => boolean;
69
+ }
70
+
71
+ /** How many rail panels get a ⌘N. §3.2 ② spends exactly this many slots, four per level group. */
72
+ export const RAIL_CHORD_LIMIT = 8;
73
+
74
+ /**
75
+ * The Inspector's four tabs, in the order §3.2 ⑨ names them — which is the order ⌘⇧1–4 follow.
76
+ *
77
+ * `"assistant"` is a different dock (it is the Inspector's second instance until P3.6 folds the
78
+ * column in), so it is not one of `shell.ts`'s `INSPECTOR_TAB_IDS`; the chord still belongs in the
79
+ * same run of four, because a user counting tabs does not know that.
80
+ */
81
+ export interface InspectorTab {
82
+ /** The stored `session.ui.rightTab` value, or `"assistant"` for the assistant dock. */
83
+ id: string;
84
+ title: string;
85
+ }
86
+
87
+ export const INSPECTOR_TABS: readonly InspectorTab[] = [
88
+ { id: "properties", title: "Content" },
89
+ { id: "style", title: "Style" },
90
+ { id: "events", title: "Logic" },
91
+ { id: "assistant", title: "Assistant" },
92
+ ];
93
+
94
+ /**
95
+ * Everything the default command set needs from the rest of Studio.
96
+ *
97
+ * One flat interface of verbs, not a bag of modules: a command's `run` is allowed to know that
98
+ * "save the document" exists, and nothing else.
99
+ */
100
+ export interface CommandDeps {
101
+ saveDocument: () => void | Promise<void>;
102
+ undo: () => void;
103
+ redo: () => void;
104
+ openInBrowser: () => void | Promise<void>;
105
+ closeDocument: () => void;
106
+ duplicateSelection: () => void;
107
+ deleteSelection: () => void;
108
+ selectParent: () => void;
109
+ toggleDock: (dock: DockId) => void;
110
+ toggleZen: () => void;
111
+ openPalette: (mode: PaletteMode) => void;
112
+ openProject: () => void | Promise<void>;
113
+ /**
114
+ * The rail's panels in rail order, then the rail-less ones — the roster ⌘1–8 is generated from.
115
+ *
116
+ * Every entry is a Navigator panel: the rail is the Navigator's, and a Bottom-dock tab is
117
+ * addressed by `view.setBottomTab` instead — one door per surface. `panels/navigator-panels.ts`'s
118
+ * `panelFocusRoster()` builds it.
119
+ *
120
+ * Injected rather than declared here so the panel registry stays the one place a panel is named,
121
+ * levelled and gated. An empty roster (the no-op deps) simply yields no `panel.focus.*` records.
122
+ */
123
+ panelRoster: readonly RailPanel[];
124
+ /**
125
+ * Toggle-FOCUS a panel (plan §5.3): reveal it and take focus, or — when it already has focus —
126
+ * collapse the dock hosting it and hand focus back to the pane. Deliberately not toggle-visible:
127
+ * ⌘1 pressed from the canvas must land you in Files, not close it.
128
+ */
129
+ focusPanel: (panelId: string) => void;
130
+ /** Show an Inspector tab and focus the dock. `"assistant"` addresses the assistant dock. */
131
+ focusInspectorTab: (tabId: string) => void;
132
+ /** F6 / ⇧F6 — move focus to the next (or previous) shell region. */
133
+ cycleRegion: (direction: 1 | -1) => void;
134
+ }
135
+
136
+ /** A dependency set whose verbs do nothing — what the CI checks load the records with. */
137
+ export function noopCommandDeps(): CommandDeps {
138
+ return {
139
+ saveDocument: () => {},
140
+ undo: () => {},
141
+ redo: () => {},
142
+ openInBrowser: () => {},
143
+ closeDocument: () => {},
144
+ duplicateSelection: () => {},
145
+ deleteSelection: () => {},
146
+ selectParent: () => {},
147
+ toggleDock: () => {},
148
+ toggleZen: () => {},
149
+ openPalette: () => {},
150
+ openProject: () => {},
151
+ panelRoster: [],
152
+ focusPanel: () => {},
153
+ focusInspectorTab: () => {},
154
+ cycleRegion: () => {},
155
+ };
156
+ }
157
+
158
+ /** A document is open and editable — the precondition most document-level verbs share. */
159
+ const documentOpen = (ctx: CommandContext) => ctx.document.open;
160
+
161
+ /**
162
+ * At least one node is selected, **on a canvas**.
163
+ *
164
+ * The editor-kind conjunct is not belt-and-braces. `keyScope` gates `handleKeyEvent` and nothing
165
+ * else, so a record reachable from the palette, the element menu, `__jxAutomation` or the assistant
166
+ * is reachable regardless of scope — and the Outline renders whatever
167
+ * `activeTab.value.doc.document` is, which with Project Settings open is the project CONFIGURATION
168
+ * object drawn as a layer tree. Clicking a row there writes `session.selection`, so Delete and
169
+ * Duplicate would transact against `project.json` and splice element nodes into the file that
170
+ * defines the project.
171
+ */
172
+ const hasSelection = (ctx: CommandContext) =>
173
+ ctx.selection.count > 0 && ctx.editor.kind === "canvas";
174
+
175
+ /**
176
+ * Every selected path names a position a structural verb can act on.
177
+ *
178
+ * Two halves, because two surfaces answer this question with different halves of the context. A
179
+ * menu opened over ONE node reports its verdict as `selection.isRoot` and carries no path list
180
+ * (`editor/context-menu.ts` builds a synthetic context from its target); the running app carries
181
+ * the real `selection.paths` and sets `isRoot` only for the document element. `isRoot` alone would
182
+ * leave a ctrl-clicked repeater template enabled — and Delete on a selection that includes one used
183
+ * to splice into a children ARRAY and throw, leaving the earlier removals applied and unrecorded.
184
+ *
185
+ * It is `every`, not `some`, deliberately: a batch that silently skips two of the five nodes the
186
+ * user selected is a worse answer than a Delete that says why it is unavailable. Offering a verb
187
+ * that cannot perform what the selection asks for is the defect, not the refusal.
188
+ */
189
+ const structurallyEditable = (ctx: CommandContext) =>
190
+ !ctx.selection.isRoot && ctx.selection.paths.every((path) => isSpliceablePath(path));
191
+
192
+ /**
193
+ * The default command set.
194
+ *
195
+ * Order is the order surfaces iterate in, so it is the order these read in the palette and in the
196
+ * Command Bar — grouped by category rather than alphabetised.
197
+ */
198
+ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
199
+ const commands: AnyCommand[] = [
200
+ // ── File / Document ──
201
+ {
202
+ id: "file.save",
203
+ title: "Save",
204
+ category: "File",
205
+ level: "document",
206
+ icon: "save",
207
+ keybinding: "mod+s",
208
+ menus: ["commandbar/primary", "statusbar/document", "palette"],
209
+ group: "1_file",
210
+ undo: "none",
211
+ when: documentOpen,
212
+ requires: "an open document",
213
+ run: () => deps.saveDocument(),
214
+ },
215
+ {
216
+ id: "document.close",
217
+ title: "Close Document",
218
+ category: "Document",
219
+ level: "document",
220
+ keybinding: "mod+w",
221
+ menus: ["context/tab", "palette"],
222
+ group: "1_file",
223
+ when: documentOpen,
224
+ requires: "an open document",
225
+ run: () => deps.closeDocument(),
226
+ },
227
+ {
228
+ id: "view.openInBrowser",
229
+ title: "Open in Browser",
230
+ category: "View",
231
+ level: "document",
232
+ icon: "browser",
233
+ keybinding: "mod+shift+o",
234
+ menus: ["commandbar/primary", "statusbar/document", "palette"],
235
+ group: "2_output",
236
+ when: (ctx) => ctx.project.isSite,
237
+ enablement: documentOpen,
238
+ requires: "a built page to open",
239
+ run: () => deps.openInBrowser(),
240
+ },
241
+
242
+ // ── Edit ──
243
+ {
244
+ id: "edit.undo",
245
+ title: "Undo",
246
+ category: "Edit",
247
+ level: "document",
248
+ icon: "undo",
249
+ keybinding: "mod+z",
250
+ menus: ["commandbar/primary", "palette"],
251
+ group: "1_history",
252
+ when: documentOpen,
253
+ enablement: (ctx) => ctx.document.canUndo,
254
+ requires: "a change to undo",
255
+ run: () => deps.undo(),
256
+ },
257
+ {
258
+ id: "edit.redo",
259
+ title: "Redo",
260
+ category: "Edit",
261
+ level: "document",
262
+ icon: "redo",
263
+ keybinding: ["mod+shift+z", "mod+y"],
264
+ menus: ["commandbar/primary", "palette"],
265
+ group: "1_history",
266
+ when: documentOpen,
267
+ enablement: (ctx) => ctx.document.canRedo,
268
+ requires: "a change to redo",
269
+ run: () => deps.redo(),
270
+ },
271
+
272
+ // ── Selection ──
273
+ // KeyScope "canvas", not "global": these chords must not fire while a text caret owns the
274
+ // Keyboard. ⌘D inside a paragraph duplicates the word, not the paragraph's element.
275
+ {
276
+ id: "selection.duplicate",
277
+ title: "Duplicate",
278
+ category: "Selection",
279
+ level: "selection",
280
+ keyScope: "canvas",
281
+ keybinding: "mod+d",
282
+ menus: ["blockbar", "context/element", "context/layer", "outline/row", "palette"],
283
+ group: "3_structure",
284
+ undo: "document",
285
+ when: hasSelection,
286
+ // Same gate as `selection.delete`: duplicating needs a sibling position to insert into. The
287
+ // Document root, a repeater template and a `$switch` case have none, and `mutateDuplicateNode`
288
+ // Would splice at a non-numeric index there — a live button that silently corrupts the
289
+ // Document. Both surfaces that render this record had to hand-guard it before the record
290
+ // Said so.
291
+ enablement: structurallyEditable,
292
+ requires: "an element that has a sibling position",
293
+ aiTool: {
294
+ name: "duplicate_node",
295
+ description: "Duplicate the currently selected element, inserting the copy after it.",
296
+ },
297
+ run: () => deps.duplicateSelection(),
298
+ },
299
+ {
300
+ id: "selection.repeat",
301
+ title: "Repeat...",
302
+ category: "Selection",
303
+ level: "selection",
304
+ keyScope: "canvas",
305
+ menus: ["context/element", "palette"],
306
+ group: "3_structure",
307
+ undo: "document",
308
+ when: hasSelection,
309
+ // Two ways to mean nothing: an element with no sibling position (`mutateInsertNode`'s
310
+ // Coordinate is the same splice index Duplicate needs), and an element that IS the repeater
311
+ // Already — its content is the single `map` template, not a child list.
312
+ enablement: (ctx) => structurallyEditable(ctx) && !ctx.selection.isRepeater,
313
+ requires: "an element with a sibling position that is not already a repeater",
314
+ aiTool: {
315
+ name: "repeat_node",
316
+ description:
317
+ "Turn the selected element into a repeater template, rendering it once per item of a " +
318
+ "data collection the author picks in the dialog this opens.",
319
+ },
320
+ /*
321
+ * The one record here whose implementation is not injected, and the reason is a property of
322
+ * the implementation rather than of this record: `convertToRepeater()` is self-contained —
323
+ * it reads the active tab, opens its own dialog and commits its own transaction — so there
324
+ * is no bootstrap state for a `CommandDeps` verb to carry, and injecting it would only mean
325
+ * the bootstrap re-exporting a function that needs nothing from the bootstrap.
326
+ *
327
+ * Imported at CALL time, which is what keeps this module's one load-bearing property intact:
328
+ * it still imports no state at module scope, so `scripts/check-command-levels.ts` and its two
329
+ * sibling checks still load the command set in a bare Bun process with no DOM.
330
+ *
331
+ * Deliberately NOT awaited, exactly as `selection.convertToComponent` is not: the promise
332
+ * resolves when a HUMAN answers the dialog, and a command whose promise waits on a person is
333
+ * a command nothing automated can call — `run()` means "start this flow".
334
+ */
335
+ run: () => {
336
+ void import("../editor/convert-to-repeater").then(({ convertToRepeater }) =>
337
+ convertToRepeater(),
338
+ );
339
+ },
340
+ },
341
+ {
342
+ id: "selection.delete",
343
+ title: "Delete",
344
+ category: "Selection",
345
+ level: "selection",
346
+ keyScope: "canvas",
347
+ keybinding: ["delete", "backspace"],
348
+ menus: ["blockbar", "context/element", "context/layer", "outline/row", "palette"],
349
+ group: "9_danger",
350
+ destructive: true,
351
+ undo: "document",
352
+ when: hasSelection,
353
+ // The document root is the document; deleting it is not an edit, it is an empty file. The
354
+ // Outline's other unspliceable rows — a repeater's map template, a `$switch` case — are
355
+ // Refused by the same gate, and refusing the whole batch is why a mixed selection can no
356
+ // Longer half-apply.
357
+ enablement: structurallyEditable,
358
+ requires: "an element selection that is not the document root",
359
+ aiTool: {
360
+ name: "delete_node",
361
+ description: "Delete the currently selected element from the document.",
362
+ },
363
+ run: () => deps.deleteSelection(),
364
+ },
365
+ {
366
+ id: "selection.selectParent",
367
+ title: "Select Parent",
368
+ category: "Selection",
369
+ level: "selection",
370
+ keyScope: "canvas",
371
+ // Two spellings of ONE action, in the record rather than in a second `keymap.add` call beside
372
+ // The registration — which is what `editor/shortcuts.ts` had to do while this file was another
373
+ // Workstream's, and is exactly the second definition site the registry exists to prevent.
374
+ keybinding: ["escape", "arrowleft"],
375
+ menus: ["palette"],
376
+ group: "2_navigate",
377
+ when: hasSelection,
378
+ requires: "an element selection",
379
+ run: () => deps.selectParent(),
380
+ },
381
+
382
+ // ── View ──
383
+ {
384
+ id: "view.toggleNavigator",
385
+ title: "Toggle Navigator Dock",
386
+ category: "View",
387
+ level: "application",
388
+ keybinding: "mod+b",
389
+ menus: ["commandbar/overflow", "palette"],
390
+ group: "4_docks",
391
+ run: () => deps.toggleDock("navigator"),
392
+ },
393
+ {
394
+ id: "view.toggleInspector",
395
+ title: "Toggle Inspector Dock",
396
+ category: "View",
397
+ level: "application",
398
+ keybinding: "mod+alt+b",
399
+ menus: ["commandbar/overflow", "palette"],
400
+ group: "4_docks",
401
+ run: () => deps.toggleDock("inspector"),
402
+ },
403
+ // `view.toggleBottomDock` (⌘J) is NOT here. It moved to `shell.ts`, beside `view.setBottomDock`
404
+ // And the `shell.docks.bottom` record both of them write: the Bottom dock is a dock now, so its
405
+ // Verbs are declared where the other two docks' are, and the toggle no longer needs a `deps`
406
+ // Hop through a dock id this module cannot resolve.
407
+ {
408
+ id: "view.zen",
409
+ title: "Zen Mode",
410
+ category: "View",
411
+ level: "application",
412
+ keybinding: "mod+.",
413
+ menus: ["commandbar/overflow", "palette"],
414
+ group: "4_docks",
415
+ run: () => deps.toggleZen(),
416
+ },
417
+
418
+ // ── Palette ──
419
+ {
420
+ id: "palette.open",
421
+ title: "Open Command Center",
422
+ category: "View",
423
+ level: "application",
424
+ keybinding: "mod+k",
425
+ menus: ["palette"],
426
+ group: "5_palette",
427
+ run: () => deps.openPalette("picker"),
428
+ },
429
+ {
430
+ id: "palette.openFiles",
431
+ title: "Go to File…",
432
+ category: "File",
433
+ level: "application",
434
+ keybinding: "mod+p",
435
+ menus: ["palette"],
436
+ group: "5_palette",
437
+ run: () => deps.openPalette("files"),
438
+ },
439
+ {
440
+ id: "palette.openCommands",
441
+ title: "Run Command…",
442
+ category: "View",
443
+ level: "application",
444
+ keybinding: "mod+shift+p",
445
+ menus: ["palette"],
446
+ group: "5_palette",
447
+ run: () => deps.openPalette("commands"),
448
+ },
449
+
450
+ {
451
+ id: "palette.openNodes",
452
+ title: "Go to Symbol in Document…",
453
+ category: "Selection",
454
+ level: "document",
455
+ menus: ["palette"],
456
+ group: "5_palette",
457
+ when: documentOpen,
458
+ requires: "an open document",
459
+ run: () => deps.openPalette("nodes"),
460
+ },
461
+
462
+ // ── Project ──
463
+ {
464
+ id: "project.open",
465
+ title: "Open Project…",
466
+ category: "Project",
467
+ level: "project",
468
+ keybinding: "mod+o",
469
+ menus: ["commandbar/overflow", "statusbar/project", "palette"],
470
+ group: "1_file",
471
+ run: () => deps.openProject(),
472
+ },
473
+ {
474
+ // The no-project palette stops being a hidden domain swap on `!projectState` and becomes a
475
+ // NAMED mode that works either way (plan §5.4) — same trigger, same chrome, stated feature.
476
+ id: "project.openRecent",
477
+ title: "Open Recent…",
478
+ category: "Project",
479
+ level: "project",
480
+ menus: ["commandbar/overflow", "statusbar/project", "palette"],
481
+ group: "1_file",
482
+ run: () => deps.openPalette("projects"),
483
+ },
484
+
485
+ // ── Direct keys (plan §5.3) ──
486
+ ...panelFocusCommands(deps),
487
+ ...inspectorFocusCommands(deps),
488
+ {
489
+ id: "view.cycleRegion",
490
+ title: "Focus Next Region",
491
+ category: "View",
492
+ level: "application",
493
+ keybinding: "f6",
494
+ menus: ["palette"],
495
+ group: "4_docks",
496
+ run: () => deps.cycleRegion(1),
497
+ },
498
+ {
499
+ id: "view.cycleRegionBack",
500
+ title: "Focus Previous Region",
501
+ category: "View",
502
+ level: "application",
503
+ keybinding: "shift+f6",
504
+ menus: ["palette"],
505
+ group: "4_docks",
506
+ run: () => deps.cycleRegion(-1),
507
+ },
508
+ ];
509
+ return commands;
510
+ }
511
+
512
+ /**
513
+ * ⌘1–8 — one record per panel, generated from {@link CommandDeps.panelRoster}.
514
+ *
515
+ * Generated rather than written out eight times for the reason the whole registry exists: the rail,
516
+ * the chord, the palette row and the generated shortcut sheet are then four renderings of one list.
517
+ * Only the first eight get a chord; a ninth panel keeps its name and its palette row, which is the
518
+ * cost §2 principle 9 puts on chrome.
519
+ */
520
+ export function panelFocusCommands(deps: CommandDeps): AnyCommand[] {
521
+ let chordsSpent = 0;
522
+ return deps.panelRoster.map((panel) => {
523
+ const command: AnyCommand = {
524
+ id: `panel.focus.${panel.id}`,
525
+ title: `Show ${panel.title}`,
526
+ category: "View",
527
+ // Application, like `view.setActivity`: revealing a panel arranges the workspace. What the
528
+ // PANEL acts on is the panel record's own level, and that is `registerPanel()`'s field.
529
+ level: "application",
530
+ menus: ["palette"],
531
+ group: "4_docks",
532
+ requires: "an open project",
533
+ // The panel's OWN `when` composes in, so a declared-but-unbuilt surface (Search, Problems)
534
+ // Has no palette row and no live chord — the record exists, the affordance does not.
535
+ when: (ctx: CommandContext) => ctx.project.open && (panel.when?.(ctx) ?? true),
536
+ run: () => deps.focusPanel(panel.id),
537
+ };
538
+ if (panel.rail !== false && chordsSpent < RAIL_CHORD_LIMIT) {
539
+ chordsSpent += 1;
540
+ command.keybinding = `mod+${chordsSpent}`;
541
+ }
542
+ return command;
543
+ });
544
+ }
545
+
546
+ /** ⌘⇧1–4 — one record per Inspector tab, generated from {@link INSPECTOR_TABS}. */
547
+ export function inspectorFocusCommands(deps: CommandDeps): AnyCommand[] {
548
+ return INSPECTOR_TABS.map((tab, index) => {
549
+ const command: AnyCommand = {
550
+ id: `inspector.focus.${tab.id}`,
551
+ title: `Show ${tab.title}`,
552
+ category: "View",
553
+ // DOCUMENT-level, like `view.setRightTab`, which writes the same field. These carried no
554
+ // `when`, no `enablement` and no `requires` at all, so with nothing open ⌘⇧2 reported success,
555
+ // Opening the right dock and moving focus there while silently NOT switching the tab —
556
+ // The delegate `focusInspectorTab` goes through `runIfPresent`, which checks `isEnabled` and skips.
557
+ // One gesture, three outcomes across the family: a loud refusal, a full write, and a
558
+ // Half-applied success with no message. The Inspector's tabs are per-document session state
559
+ // (`session.ui.rightTab`), so the document is the honest precondition.
560
+ level: "document",
561
+ keybinding: `mod+shift+${index + 1}`,
562
+ menus: ["palette"],
563
+ group: "4_docks",
564
+ requires: "an open document",
565
+ when: (ctx: CommandContext) => ctx.document.open,
566
+ run: () => deps.focusInspectorTab(tab.id),
567
+ };
568
+ return command;
569
+ });
570
+ }
571
+
572
+ /**
573
+ * The default set with no-op implementations — the shape the CI checks validate.
574
+ *
575
+ * `scripts/check-command-levels.ts` and `scripts/check-chrome-budget.ts` both call this by name; a
576
+ * fixture module passed with `--source` exports the same function.
577
+ */
578
+ export function defaultCommandSet(): AnyCommand[] {
579
+ return defaultCommands(noopCommandDeps());
580
+ }