@jxsuite/studio 6.1.0 → 6.1.2

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 (645) hide show
  1. package/dist/chunks/2020-f2gkpy8d.js +4 -0
  2. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  3. package/dist/chunks/adapter-4912g339.js +4 -0
  4. package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
  5. package/dist/chunks/cf-settings-br6105tr.js +4 -0
  6. package/dist/chunks/color-28ksk2qm.js +4 -0
  7. package/dist/chunks/color-area-0fj8a4ga.js +4 -0
  8. package/dist/chunks/color-field-xch8kx2g.js +4 -0
  9. package/dist/chunks/color-slider-jxd8v350.js +4 -0
  10. package/dist/chunks/combobox-p0efwjke.js +4 -0
  11. package/dist/chunks/components-db68vsn7.js +4 -0
  12. package/dist/chunks/content-source-1449qesq.js +4 -0
  13. package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
  14. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  15. package/dist/chunks/editor-x9jn86a7.js +4 -0
  16. package/dist/chunks/entry-commands-may24cpt.js +4 -0
  17. package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
  18. package/dist/chunks/file-ops-x9v54pcj.js +4 -0
  19. package/dist/chunks/files-j3knqf0s.js +4 -0
  20. package/dist/chunks/format-host-tyre2trb.js +4 -0
  21. package/dist/chunks/fs-events-64ma9htc.js +4 -0
  22. package/dist/chunks/git-panel-84ps5dex.js +4 -0
  23. package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
  24. package/dist/chunks/icons-pnfz478q.js +4 -0
  25. package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
  26. package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
  27. package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
  28. package/dist/chunks/iframe-entry-zap785cw.js +5 -0
  29. package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
  30. package/dist/chunks/index-b8xw3vy9.js +4 -0
  31. package/dist/chunks/{index-gybvv7a6.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-rnvdp3k4.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/jsonMode-w15cmrcm.js +13 -0
  34. package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
  35. package/dist/chunks/layers-h4xp1pss.js +4 -0
  36. package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
  37. package/dist/chunks/listbox-e74qjyq6.js +4 -0
  38. package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
  39. package/dist/chunks/media-picker-2cweexc5.js +4 -0
  40. package/dist/chunks/menu-n6yzswmy.js +4 -0
  41. package/dist/chunks/menu-ynw13y0s.js +4 -0
  42. package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
  43. package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
  44. package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
  45. package/dist/chunks/notify-cj5zbrs2.js +4 -0
  46. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  47. package/dist/chunks/parse-b7ddhr8m.js +4 -0
  48. package/dist/chunks/platform-3dfws9js.js +4 -0
  49. package/dist/chunks/popover-jt2gxmzs.js +4 -0
  50. package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
  51. package/dist/chunks/quick-search-0dajrwqg.js +4 -0
  52. package/dist/chunks/references-49qgt404.js +4 -0
  53. package/dist/chunks/right-panel-jm1bwe53.js +4 -0
  54. package/dist/chunks/section-registry-6kwc4fky.js +4 -0
  55. package/dist/chunks/select-rzds841e.js +4 -0
  56. package/dist/chunks/split-n2gfpm5m.js +4 -0
  57. package/dist/chunks/{studio-5g0ag7c0.js → studio-0q988f9w.js} +3 -3
  58. package/dist/chunks/studio-0rt52vpq.js +5 -0
  59. package/dist/chunks/studio-18vgbhs5.js +5 -0
  60. package/dist/chunks/{studio-pxg4ap1e.js → studio-1fxkaaea.js} +4 -4
  61. package/dist/chunks/studio-24mccdrj.js +5 -0
  62. package/dist/chunks/studio-2eh507zk.js +9 -0
  63. package/dist/chunks/studio-2hcbccfv.js +5 -0
  64. package/dist/chunks/studio-2j1cb95x.js +5 -0
  65. package/dist/chunks/studio-2jbs3rxv.js +5 -0
  66. package/dist/chunks/{studio-qbj760tx.js → studio-485046te.js} +7 -7
  67. package/dist/chunks/studio-4h8k4dw9.js +5 -0
  68. package/dist/chunks/studio-5f6n18kx.js +5 -0
  69. package/dist/chunks/studio-5gthpky6.js +5 -0
  70. package/dist/chunks/studio-5ve6bbep.js +5 -0
  71. package/dist/chunks/studio-6ep3js6b.js +9 -0
  72. package/dist/chunks/studio-6wkmf3wz.js +9 -0
  73. package/dist/chunks/studio-841rf3cg.js +5 -0
  74. package/dist/chunks/studio-8gmwgheg.js +5 -0
  75. package/dist/chunks/studio-8qm0ep50.js +5 -0
  76. package/dist/chunks/{studio-anyrgzvb.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-v2bvmbjj.js → studio-a3g98wjr.js} +4 -4
  79. package/dist/chunks/studio-a3shpz9y.js +5 -0
  80. package/dist/chunks/studio-amsbaaar.js +6 -0
  81. package/dist/chunks/studio-at5spjbc.js +7 -0
  82. package/dist/chunks/studio-b2xv945e.js +5 -0
  83. package/dist/chunks/studio-bn5nkafw.js +5 -0
  84. package/dist/chunks/studio-bw6q5xjf.js +9 -0
  85. package/dist/chunks/studio-c7q0t9x1.js +5 -0
  86. package/dist/chunks/studio-camnhc96.js +6 -0
  87. package/dist/chunks/studio-cffqvnzd.js +5 -0
  88. package/dist/chunks/studio-d81xfh1g.js +5 -0
  89. package/dist/chunks/studio-dgz8d0c1.js +5 -0
  90. package/dist/chunks/studio-efvfrsf8.js +5 -0
  91. package/dist/chunks/studio-er30bpcx.js +5 -0
  92. package/dist/chunks/studio-ezscgr64.js +5 -0
  93. package/dist/chunks/studio-ffrrncvz.js +5 -0
  94. package/dist/chunks/studio-fpphgn8y.js +10 -0
  95. package/dist/chunks/studio-j1kvhdjk.js +4 -0
  96. package/dist/chunks/{studio-txjjzrsm.js → studio-j430n16g.js} +5 -5
  97. package/dist/chunks/studio-jjkg84nj.js +5 -0
  98. package/dist/chunks/studio-m0q32ars.js +4 -0
  99. package/dist/chunks/studio-m6bdst11.js +5 -0
  100. package/dist/chunks/studio-nv2cptd4.js +64 -0
  101. package/dist/chunks/studio-nwfrc98n.js +5 -0
  102. package/dist/chunks/studio-p1wgvp7r.js +5 -0
  103. package/dist/chunks/studio-pag2wncm.js +5 -0
  104. package/dist/chunks/studio-qvanvzfd.js +5 -0
  105. package/dist/chunks/studio-qwa64kt7.js +5 -0
  106. package/dist/chunks/studio-rk1zc4x3.js +928 -0
  107. package/dist/chunks/studio-se2r3ptc.js +5 -0
  108. package/dist/chunks/studio-sg2a0dh0.js +5 -0
  109. package/dist/chunks/studio-tjzjhe68.js +5 -0
  110. package/dist/chunks/{studio-0x3jyb8r.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-cpxkgjrj.js → studio-v0jzqdjm.js} +4 -4
  112. package/dist/chunks/studio-v2w7q8r1.js +7 -0
  113. package/dist/chunks/studio-v5vjq1h0.js +4 -0
  114. package/dist/chunks/studio-v8aga3vp.js +14 -0
  115. package/dist/chunks/studio-vfcdrfmv.js +5 -0
  116. package/dist/chunks/studio-vmfkgdjf.js +5 -0
  117. package/dist/chunks/studio-wt1816jj.js +5 -0
  118. package/dist/chunks/studio-wz73q5kq.js +4 -0
  119. package/dist/chunks/studio-y04qtxvp.js +7 -0
  120. package/dist/chunks/studio-y21g8zzg.js +5 -0
  121. package/dist/chunks/studio-y64hrt8p.js +12 -0
  122. package/dist/chunks/studio-ynn90f58.js +16 -0
  123. package/dist/chunks/studio-yxz682sx.js +5 -0
  124. package/dist/chunks/studio-zp7snvkq.js +5 -0
  125. package/dist/chunks/studio-zq4z6tm6.js +5 -0
  126. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  127. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  128. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  129. package/dist/chunks/toast-c9fn075p.js +4 -0
  130. package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
  131. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  132. package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
  133. package/dist/chunks/tree-mdq3v5cw.js +4 -0
  134. package/dist/chunks/tsMode-sf49ee9x.js +14 -0
  135. package/dist/chunks/workspace-jtfahpee.js +4 -0
  136. package/dist/chunks/ws-client-nze0k6mv.js +4 -0
  137. package/dist/iframe-entry.js +16 -16
  138. package/dist/manifest.json +63 -63
  139. package/dist/studio.js +98 -98
  140. package/dist/workers/ts.worker.js +3 -3
  141. package/package.json +11 -11
  142. package/src/about/about-modal.ts +4 -3
  143. package/src/account/action-flow.ts +45 -38
  144. package/src/account-status.ts +7 -2
  145. package/src/browse/library-layouts.ts +8 -5
  146. package/src/browse/library-model.ts +18 -6
  147. package/src/browse/library-pane.ts +37 -21
  148. package/src/browse/library-preview.ts +14 -9
  149. package/src/browse/library-source.ts +1 -1
  150. package/src/canvas/asset-refs.ts +24 -9
  151. package/src/canvas/asset-resolve.ts +19 -23
  152. package/src/canvas/canvas-helpers.ts +7 -6
  153. package/src/canvas/canvas-live-render.ts +44 -53
  154. package/src/canvas/canvas-patcher.ts +30 -30
  155. package/src/canvas/canvas-perf.ts +11 -5
  156. package/src/canvas/canvas-render.ts +66 -42
  157. package/src/canvas/canvas-surface.ts +5 -3
  158. package/src/canvas/canvas-utils.ts +163 -64
  159. package/src/canvas/dialog-path.ts +9 -4
  160. package/src/canvas/dialog-state.ts +1 -2
  161. package/src/canvas/diff-marks.ts +9 -16
  162. package/src/canvas/diff-toolbar.ts +8 -7
  163. package/src/canvas/edit-width-drag.ts +4 -1
  164. package/src/canvas/edit-width.ts +1 -3
  165. package/src/canvas/iframe-channel.ts +27 -13
  166. package/src/canvas/iframe-drop.ts +13 -12
  167. package/src/canvas/iframe-editable-root.ts +29 -16
  168. package/src/canvas/iframe-entry.ts +80 -63
  169. package/src/canvas/iframe-eval.ts +73 -49
  170. package/src/canvas/iframe-host.ts +203 -118
  171. package/src/canvas/iframe-inline-edit.ts +69 -32
  172. package/src/canvas/iframe-insert.ts +5 -4
  173. package/src/canvas/iframe-interaction.ts +37 -26
  174. package/src/canvas/iframe-overlay.ts +1 -1
  175. package/src/canvas/iframe-patch.ts +18 -15
  176. package/src/canvas/iframe-position.ts +12 -6
  177. package/src/canvas/iframe-protocol.ts +15 -16
  178. package/src/canvas/iframe-render.ts +41 -36
  179. package/src/canvas/iframe-slash.ts +24 -11
  180. package/src/canvas/iframe-subtree.ts +6 -2
  181. package/src/canvas/path-mapping.ts +19 -12
  182. package/src/canvas/popover-path.ts +7 -3
  183. package/src/canvas/popover-state.ts +1 -2
  184. package/src/canvas/serialize-scope.ts +13 -5
  185. package/src/canvas/stage-scrollbar.ts +2 -1
  186. package/src/canvas/surface-registry.ts +21 -3
  187. package/src/collab/collab-commands.ts +7 -2
  188. package/src/collab/collab-session.ts +84 -45
  189. package/src/collab/collab-state.ts +4 -3
  190. package/src/collab/monaco-binding.ts +16 -13
  191. package/src/collab/monaco-cursors.ts +5 -2
  192. package/src/commands/budget.ts +3 -3
  193. package/src/commands/command-args.ts +103 -71
  194. package/src/commands/context.ts +22 -20
  195. package/src/commands/defaults.ts +4 -1
  196. package/src/commands/keymap.ts +47 -43
  197. package/src/commands/levels.ts +3 -3
  198. package/src/commands/live-context.ts +10 -8
  199. package/src/commands/reference.ts +2 -1
  200. package/src/commands/registry.ts +12 -10
  201. package/src/commands/run-reported.ts +15 -10
  202. package/src/component-props.ts +46 -30
  203. package/src/content/collection-match.ts +5 -4
  204. package/src/content/draft-state.ts +4 -3
  205. package/src/content/entry-commands.ts +3 -2
  206. package/src/content/entry-editor.ts +29 -17
  207. package/src/content/entry-fields.ts +12 -7
  208. package/src/content/entry-model.ts +21 -12
  209. package/src/editor/canvas-context-menu.ts +1 -2
  210. package/src/editor/canvas-slash-bridge.ts +3 -6
  211. package/src/editor/content-slice.ts +16 -14
  212. package/src/editor/context-menu.ts +35 -22
  213. package/src/editor/convert-targets.ts +30 -35
  214. package/src/editor/convert-to-component.ts +11 -5
  215. package/src/editor/convert-to-repeater.ts +34 -22
  216. package/src/editor/editable-tags.ts +17 -2
  217. package/src/editor/file-drop-action.ts +21 -22
  218. package/src/editor/inline-edit-apply.ts +35 -17
  219. package/src/editor/inline-edit.ts +66 -50
  220. package/src/editor/inline-format.ts +59 -56
  221. package/src/editor/inline-link.ts +40 -15
  222. package/src/editor/insert-zone-action.ts +1 -1
  223. package/src/editor/merge-tags.ts +58 -19
  224. package/src/editor/repeater-scope.ts +39 -28
  225. package/src/editor/shortcuts.ts +87 -47
  226. package/src/editor/slash-menu.ts +1 -6
  227. package/src/files/asset-versions.ts +4 -4
  228. package/src/files/components.ts +15 -10
  229. package/src/files/elements.ts +5 -6
  230. package/src/files/file-ops.ts +77 -36
  231. package/src/files/files.ts +90 -95
  232. package/src/files/media-meta.ts +2 -1
  233. package/src/files/media-paths.ts +6 -1
  234. package/src/files/serialize-document.ts +2 -2
  235. package/src/format/constraints.ts +1 -1
  236. package/src/format/convert-file.ts +27 -13
  237. package/src/format/format-choices.ts +2 -1
  238. package/src/format/format-host.ts +76 -50
  239. package/src/github/github-auth-status.ts +27 -3
  240. package/src/github/github-auth.ts +19 -9
  241. package/src/github/github-publish.ts +24 -20
  242. package/src/grid/cell-editors.ts +46 -31
  243. package/src/grid/cell-popovers.ts +5 -3
  244. package/src/grid/edit-buffer.ts +10 -9
  245. package/src/grid/grid-controller.ts +20 -22
  246. package/src/grid/grid-layout.ts +21 -5
  247. package/src/grid/grid-open.ts +3 -6
  248. package/src/grid/grid-panel.ts +11 -4
  249. package/src/grid/grid-source.ts +8 -8
  250. package/src/grid/grid-view.ts +14 -17
  251. package/src/grid/redirects-grid.ts +14 -5
  252. package/src/grid/redirects.ts +16 -14
  253. package/src/grid/schema-columns.ts +25 -19
  254. package/src/grid/sources/connector-source.ts +47 -20
  255. package/src/grid/sources/content-source.ts +25 -24
  256. package/src/grid/sources/csv-file-source.ts +2 -2
  257. package/src/grid/tabulator-tables.d.ts +55 -34
  258. package/src/hosting/stage.ts +7 -7
  259. package/src/i18n/i18n-commands.ts +1 -2
  260. package/src/media/media-pane.ts +4 -1
  261. package/src/new-project/add-repo-modal.ts +20 -19
  262. package/src/new-project/import-tab.ts +10 -14
  263. package/src/new-project/location-fields.ts +2 -1
  264. package/src/new-project/new-project-modal.ts +12 -9
  265. package/src/packages/jxsuite-update.ts +4 -3
  266. package/src/packages/pull-package-sync.ts +26 -25
  267. package/src/page-params.ts +97 -68
  268. package/src/panels/activity-panel.ts +17 -9
  269. package/src/panels/ai-chat/attached-context.ts +13 -7
  270. package/src/panels/ai-chat/chat-view.ts +80 -73
  271. package/src/panels/ai-chat/composer.ts +30 -33
  272. package/src/panels/ai-chat/sessions-view.ts +1 -2
  273. package/src/panels/ai-panel.ts +23 -20
  274. package/src/panels/block-action-bar.ts +46 -35
  275. package/src/panels/bottom-dock.ts +5 -3
  276. package/src/panels/canvas-dnd-bridge.ts +31 -24
  277. package/src/panels/data-explorer.ts +62 -25
  278. package/src/panels/data-grid.ts +14 -11
  279. package/src/panels/dnd.ts +108 -118
  280. package/src/panels/editors.ts +55 -22
  281. package/src/panels/elements-panel.ts +10 -3
  282. package/src/panels/events-panel.ts +84 -69
  283. package/src/panels/formula-workspace.ts +76 -51
  284. package/src/panels/frontmatter-fields.ts +24 -19
  285. package/src/panels/frontmatter-panel.ts +44 -34
  286. package/src/panels/git-diff-open.ts +4 -4
  287. package/src/panels/git-panel.ts +49 -61
  288. package/src/panels/head-panel.ts +131 -111
  289. package/src/panels/i18n-panel.ts +10 -3
  290. package/src/panels/imports-panel.ts +23 -47
  291. package/src/panels/jump-bar.ts +48 -29
  292. package/src/panels/layers-panel.ts +97 -74
  293. package/src/panels/left-panel.ts +3 -3
  294. package/src/panels/pane-context.ts +31 -22
  295. package/src/panels/pane-grid.ts +49 -20
  296. package/src/panels/panel-registry.ts +22 -37
  297. package/src/panels/properties-panel.ts +175 -121
  298. package/src/panels/quick-search.ts +53 -31
  299. package/src/panels/right-panel.ts +3 -3
  300. package/src/panels/seo-modal.ts +13 -17
  301. package/src/panels/settings-menu.ts +15 -15
  302. package/src/panels/signals-panel.ts +153 -131
  303. package/src/panels/statement-editor.ts +230 -140
  304. package/src/panels/style-panel.ts +254 -216
  305. package/src/panels/style-utils.ts +114 -51
  306. package/src/panels/stylebook-doc.ts +57 -54
  307. package/src/panels/stylebook-layers-panel.ts +9 -9
  308. package/src/panels/stylebook-panel.ts +13 -17
  309. package/src/panels/tab-drop.ts +27 -11
  310. package/src/panels/tab-strip.ts +36 -26
  311. package/src/platform-errors.ts +57 -43
  312. package/src/platform.ts +58 -30
  313. package/src/platforms/cloud.ts +345 -175
  314. package/src/platforms/default-platform.ts +10 -4
  315. package/src/platforms/devserver.ts +174 -127
  316. package/src/platforms/read-batcher.ts +16 -8
  317. package/src/project-list.ts +2 -1
  318. package/src/publish/deploy-checklist.ts +8 -2
  319. package/src/publish/pages-service.ts +28 -13
  320. package/src/publish/publish-commands.ts +5 -4
  321. package/src/publish/publish-panel.ts +10 -6
  322. package/src/recent-projects.ts +15 -8
  323. package/src/resize-edges.ts +26 -36
  324. package/src/services/a11y-report.ts +26 -19
  325. package/src/services/agent-seed.ts +23 -11
  326. package/src/services/ai-ask.ts +9 -12
  327. package/src/services/ai-command-tools.ts +68 -62
  328. package/src/services/ai-import-tools.ts +80 -67
  329. package/src/services/ai-models.ts +17 -13
  330. package/src/services/ai-project-tools.ts +68 -32
  331. package/src/services/ai-session-store.ts +19 -10
  332. package/src/services/ai-system-prompt.ts +46 -20
  333. package/src/services/ai-tools.ts +71 -27
  334. package/src/services/ai-write-report.ts +20 -12
  335. package/src/services/ai-writes.ts +4 -4
  336. package/src/services/automation.ts +58 -31
  337. package/src/services/cem-export.ts +149 -58
  338. package/src/services/clock.ts +6 -1
  339. package/src/services/code-services.ts +37 -31
  340. package/src/services/context-manager.ts +14 -10
  341. package/src/services/context-resolver.ts +20 -8
  342. package/src/services/data-service.ts +19 -15
  343. package/src/services/directory-picker.ts +18 -12
  344. package/src/services/document-assistant.ts +39 -19
  345. package/src/services/gated-registry.ts +10 -6
  346. package/src/services/harness/chat-reducer.ts +23 -1
  347. package/src/services/import-client.ts +91 -38
  348. package/src/services/import-seed.ts +8 -2
  349. package/src/services/jx-validate.ts +28 -31
  350. package/src/services/live-preview.ts +0 -0
  351. package/src/services/live-surfaces.ts +6 -3
  352. package/src/services/model-uri.ts +10 -2
  353. package/src/services/module-preloads.ts +12 -8
  354. package/src/services/monaco-buffer.ts +43 -24
  355. package/src/services/monaco-lazy.ts +7 -8
  356. package/src/services/monaco-setup.ts +23 -16
  357. package/src/services/notify.ts +44 -17
  358. package/src/services/popover-report.ts +25 -10
  359. package/src/services/preview-eval.ts +20 -8
  360. package/src/services/profile.ts +13 -6
  361. package/src/services/project-path.ts +13 -10
  362. package/src/services/references.ts +0 -0
  363. package/src/services/render-critic.ts +8 -7
  364. package/src/services/settings/kernel.ts +13 -4
  365. package/src/services/settings/write-queue.ts +9 -9
  366. package/src/services/token-lint.ts +12 -10
  367. package/src/services/tool-executor.ts +17 -5
  368. package/src/services/tool-outcomes.ts +44 -24
  369. package/src/services/trusted-types.ts +24 -7
  370. package/src/settings/contexts-section.ts +11 -8
  371. package/src/settings/contributed-section.ts +79 -60
  372. package/src/settings/css-vars-editor.ts +37 -16
  373. package/src/settings/defs-editor.ts +38 -35
  374. package/src/settings/extension-rows.ts +16 -8
  375. package/src/settings/extension-sections.ts +23 -13
  376. package/src/settings/extensions-section.ts +4 -1
  377. package/src/settings/general-settings.ts +11 -8
  378. package/src/settings/locales-section.ts +20 -12
  379. package/src/settings/preferences-dialog.ts +9 -6
  380. package/src/settings/preferences-keymap.ts +7 -5
  381. package/src/settings/preferences-sections.ts +11 -5
  382. package/src/settings/project-sections.ts +1 -1
  383. package/src/settings/schema-field-ui.ts +9 -0
  384. package/src/settings/settings-document.ts +5 -5
  385. package/src/shell/tree.ts +6 -5
  386. package/src/shell.ts +104 -81
  387. package/src/site-context.ts +37 -22
  388. package/src/state.ts +41 -49
  389. package/src/store.ts +54 -34
  390. package/src/studio.ts +39 -77
  391. package/src/style/live-preview.ts +1 -1
  392. package/src/style/project-styles.ts +6 -7
  393. package/src/style/token-ref.ts +5 -4
  394. package/src/surfaces/about.ts +18 -19
  395. package/src/surfaces/add-repo.ts +17 -19
  396. package/src/surfaces/ai-chat.ts +31 -36
  397. package/src/surfaces/ai-credentials-form.ts +6 -16
  398. package/src/surfaces/ai-managed-connect.ts +3 -4
  399. package/src/surfaces/ai-model-picker.ts +3 -5
  400. package/src/surfaces/block-action-bar.ts +22 -11
  401. package/src/surfaces/boot-failure.ts +4 -5
  402. package/src/surfaces/bottom-dock.ts +9 -18
  403. package/src/surfaces/canvas-stage.ts +12 -11
  404. package/src/surfaces/cf-account-picker.ts +17 -18
  405. package/src/surfaces/commandbar.ts +14 -9
  406. package/src/surfaces/convert-repeater.ts +17 -19
  407. package/src/surfaces/data-actions.ts +9 -7
  408. package/src/surfaces/dialog.ts +26 -28
  409. package/src/surfaces/diff-toolbar.ts +9 -7
  410. package/src/surfaces/doc-header.ts +10 -19
  411. package/src/surfaces/empty-state.ts +7 -10
  412. package/src/surfaces/entry-editor.ts +14 -11
  413. package/src/surfaces/expression-editor.ts +11 -25
  414. package/src/surfaces/files-panel.ts +27 -14
  415. package/src/surfaces/formula-palette.ts +4 -5
  416. package/src/surfaces/git-panel.ts +7 -15
  417. package/src/surfaces/github-auth.ts +16 -20
  418. package/src/surfaces/github-publish.ts +17 -22
  419. package/src/surfaces/grid-cell.ts +30 -31
  420. package/src/surfaces/grid-open.ts +10 -14
  421. package/src/surfaces/grid-panel.ts +13 -9
  422. package/src/surfaces/grid-replace.ts +13 -13
  423. package/src/surfaces/grid-views.ts +15 -18
  424. package/src/surfaces/inspector-dock.ts +13 -12
  425. package/src/surfaces/jump-bar.ts +5 -6
  426. package/src/surfaces/jxsuite-update.ts +16 -22
  427. package/src/surfaces/library-pane.ts +25 -20
  428. package/src/surfaces/logic-panel.ts +17 -30
  429. package/src/surfaces/logic-workspace.ts +13 -15
  430. package/src/surfaces/media-browser.ts +11 -10
  431. package/src/surfaces/media-field.ts +4 -5
  432. package/src/surfaces/media-pane.ts +8 -7
  433. package/src/surfaces/menu.ts +29 -23
  434. package/src/surfaces/navigator-dock.ts +11 -12
  435. package/src/surfaces/new-project.ts +27 -26
  436. package/src/surfaces/pane-context.ts +20 -25
  437. package/src/surfaces/pane-grid.ts +15 -10
  438. package/src/surfaces/panel-activity.ts +5 -6
  439. package/src/surfaces/panel-data.ts +3 -4
  440. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  441. package/src/surfaces/panel-elements.ts +5 -7
  442. package/src/surfaces/panel-i18n.ts +5 -7
  443. package/src/surfaces/panel-imports.ts +6 -13
  444. package/src/surfaces/panel-outline.ts +25 -19
  445. package/src/surfaces/panel-page.ts +11 -18
  446. package/src/surfaces/panel-problems.ts +5 -7
  447. package/src/surfaces/panel-signals.ts +20 -34
  448. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  449. package/src/surfaces/preferences.ts +21 -11
  450. package/src/surfaces/progress-modal.ts +15 -9
  451. package/src/surfaces/properties-panel.json +1 -1
  452. package/src/surfaces/properties-panel.ts +20 -42
  453. package/src/surfaces/publish.ts +18 -18
  454. package/src/surfaces/push-plan.ts +7 -8
  455. package/src/surfaces/rail.json +126 -73
  456. package/src/surfaces/rail.ts +38 -12
  457. package/src/surfaces/reference-field.ts +11 -15
  458. package/src/surfaces/schema-builder.ts +16 -22
  459. package/src/surfaces/schema-form.ts +15 -25
  460. package/src/surfaces/secret-field.ts +9 -6
  461. package/src/surfaces/seo.ts +21 -15
  462. package/src/surfaces/settings-contexts.ts +9 -7
  463. package/src/surfaces/settings-contributed.ts +14 -10
  464. package/src/surfaces/settings-css-vars.ts +5 -12
  465. package/src/surfaces/settings-defs.json +2 -2
  466. package/src/surfaces/settings-defs.ts +17 -21
  467. package/src/surfaces/settings-deploy.ts +8 -15
  468. package/src/surfaces/settings-extensions.ts +5 -6
  469. package/src/surfaces/settings-head.ts +33 -39
  470. package/src/surfaces/settings-locales.ts +8 -20
  471. package/src/surfaces/settings-overview.ts +5 -6
  472. package/src/surfaces/settings-packages.ts +8 -7
  473. package/src/surfaces/settings-pane.ts +9 -18
  474. package/src/surfaces/settings-rawjson.ts +5 -6
  475. package/src/surfaces/shell.ts +1 -2
  476. package/src/surfaces/slash-menu.ts +19 -9
  477. package/src/surfaces/statements.ts +13 -18
  478. package/src/surfaces/statusbar.ts +17 -14
  479. package/src/surfaces/style-panel.ts +18 -31
  480. package/src/surfaces/stylebook-chrome.ts +3 -5
  481. package/src/surfaces/tab-strip.ts +14 -13
  482. package/src/surfaces/target-line.ts +6 -7
  483. package/src/surfaces/welcome.ts +5 -7
  484. package/src/tabs/patch-ops.ts +4 -3
  485. package/src/tabs/project-config.ts +32 -21
  486. package/src/tabs/selection.ts +36 -8
  487. package/src/tabs/tab.ts +52 -41
  488. package/src/tabs/transact.ts +98 -53
  489. package/src/tabs/typing.ts +31 -0
  490. package/src/types.ts +32 -17
  491. package/src/ui/ai-credentials-form.ts +10 -13
  492. package/src/ui/ai-model-picker.ts +3 -3
  493. package/src/ui/cf-account-picker.ts +7 -9
  494. package/src/ui/color-selector.ts +9 -5
  495. package/src/ui/dynamic-slot.ts +7 -8
  496. package/src/ui/expression-editor.ts +112 -105
  497. package/src/ui/form-controls.ts +57 -48
  498. package/src/ui/formula-catalog.ts +239 -230
  499. package/src/ui/formula-chips.ts +33 -18
  500. package/src/ui/layers.ts +44 -31
  501. package/src/ui/media-picker.ts +18 -9
  502. package/src/ui/popover-surface.ts +20 -12
  503. package/src/ui/progress-modal.ts +13 -8
  504. package/src/ui/regions.ts +7 -6
  505. package/src/ui/schema-form.ts +113 -70
  506. package/src/ui/surface.ts +71 -8
  507. package/src/ui/timing.ts +9 -0
  508. package/src/ui/value-source.ts +44 -31
  509. package/src/ui/virtual-window.ts +3 -2
  510. package/src/utils/base64.ts +3 -1
  511. package/src/utils/edit-display.ts +103 -74
  512. package/src/utils/element-selectors.ts +3 -2
  513. package/src/utils/google-fonts.ts +15 -14
  514. package/src/utils/inherited-style.ts +18 -20
  515. package/src/utils/link-target.ts +1 -1
  516. package/src/utils/preview-format.ts +25 -3
  517. package/src/utils/strip-events.ts +49 -22
  518. package/src/utils/studio-utils.ts +29 -14
  519. package/src/view.ts +2 -3
  520. package/src/workspace/pane-derive.ts +10 -12
  521. package/src/workspace/session.ts +53 -43
  522. package/src/workspace/workspace.ts +47 -36
  523. package/dist/chunks/2020-nkxms0ay.js +0 -4
  524. package/dist/chunks/adapter-m948ab5f.js +0 -4
  525. package/dist/chunks/cf-account-picker-n8hr38v7.js +0 -4
  526. package/dist/chunks/cf-settings-356xdtne.js +0 -4
  527. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  528. package/dist/chunks/color-field-embq5ctg.js +0 -4
  529. package/dist/chunks/color-fpezvnkt.js +0 -4
  530. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  531. package/dist/chunks/combobox-773hdzyj.js +0 -4
  532. package/dist/chunks/components-yk3t844e.js +0 -4
  533. package/dist/chunks/content-source-bawmyc09.js +0 -4
  534. package/dist/chunks/convert-to-repeater-7wns8kf1.js +0 -4
  535. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  536. package/dist/chunks/editor-6sc8nacq.js +0 -4
  537. package/dist/chunks/entry-commands-8ay9fh81.js +0 -4
  538. package/dist/chunks/extension-sections-na7rj3nr.js +0 -4
  539. package/dist/chunks/file-ops-gye0qw56.js +0 -4
  540. package/dist/chunks/files-dmc2xvcq.js +0 -4
  541. package/dist/chunks/format-host-t76b53f8.js +0 -4
  542. package/dist/chunks/fs-events-cg4tpz06.js +0 -4
  543. package/dist/chunks/git-panel-yef7bshy.js +0 -4
  544. package/dist/chunks/grid-view-7tt4bxw1.js +0 -51
  545. package/dist/chunks/icons-qbh8akb1.js +0 -4
  546. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  547. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  548. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  549. package/dist/chunks/iframe-host-tmz30gfp.js +0 -4
  550. package/dist/chunks/index-nag78a9h.js +0 -4
  551. package/dist/chunks/jsonMode-zhwsprqk.js +0 -13
  552. package/dist/chunks/jx-validate-3gbp5nkn.js +0 -4
  553. package/dist/chunks/layers-fvz99859.js +0 -4
  554. package/dist/chunks/layers-panel-gchmbf9p.js +0 -4
  555. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  556. package/dist/chunks/lit-html-9agdspkt.js +0 -4
  557. package/dist/chunks/media-picker-rhjvyy00.js +0 -4
  558. package/dist/chunks/menu-2e4y9j7b.js +0 -4
  559. package/dist/chunks/menu-37d07z9m.js +0 -4
  560. package/dist/chunks/monaco-binding-2jnhjjvr.js +0 -4
  561. package/dist/chunks/monaco-buffer-rp21359g.js +0 -4
  562. package/dist/chunks/monaco-setup-vhh7gayr.js +0 -4
  563. package/dist/chunks/notify-h3www560.js +0 -4
  564. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  565. package/dist/chunks/parse-897fvqah.js +0 -4
  566. package/dist/chunks/platform-hz34wcd7.js +0 -4
  567. package/dist/chunks/popover-8htra4er.js +0 -4
  568. package/dist/chunks/publish-panel-exsmjzyj.js +0 -4
  569. package/dist/chunks/quick-search-pgaqeh0m.js +0 -4
  570. package/dist/chunks/references-2cgdxnb8.js +0 -4
  571. package/dist/chunks/right-panel-jf856w5w.js +0 -4
  572. package/dist/chunks/section-registry-jnf8r5gy.js +0 -4
  573. package/dist/chunks/select-n3v7gwas.js +0 -4
  574. package/dist/chunks/split-pff8f3ze.js +0 -4
  575. package/dist/chunks/studio-0f55h9ye.js +0 -5
  576. package/dist/chunks/studio-0sqdhnew.js +0 -12
  577. package/dist/chunks/studio-19x1c75w.js +0 -5
  578. package/dist/chunks/studio-2sqcndak.js +0 -5
  579. package/dist/chunks/studio-3aey7dd3.js +0 -5
  580. package/dist/chunks/studio-3bpdkq2s.js +0 -5
  581. package/dist/chunks/studio-47y6fbpf.js +0 -5
  582. package/dist/chunks/studio-4m3826v2.js +0 -5
  583. package/dist/chunks/studio-4nx2dj1g.js +0 -4
  584. package/dist/chunks/studio-4xv5s47r.js +0 -9
  585. package/dist/chunks/studio-5g4t8v6w.js +0 -5
  586. package/dist/chunks/studio-5py436sf.js +0 -5
  587. package/dist/chunks/studio-77kt594t.js +0 -5
  588. package/dist/chunks/studio-8f87n763.js +0 -10
  589. package/dist/chunks/studio-8mb00b84.js +0 -5
  590. package/dist/chunks/studio-8p51gq2h.js +0 -6
  591. package/dist/chunks/studio-954ds834.js +0 -5
  592. package/dist/chunks/studio-9ft45c83.js +0 -9
  593. package/dist/chunks/studio-a2138x5k.js +0 -7
  594. package/dist/chunks/studio-a9yzstqj.js +0 -5
  595. package/dist/chunks/studio-acdksxx6.js +0 -5
  596. package/dist/chunks/studio-ar8jcf2y.js +0 -5
  597. package/dist/chunks/studio-bmn4mn9j.js +0 -7
  598. package/dist/chunks/studio-e7xxa0sj.js +0 -5
  599. package/dist/chunks/studio-ecaz25vk.js +0 -5
  600. package/dist/chunks/studio-ery42sqr.js +0 -4
  601. package/dist/chunks/studio-fzdywr6p.js +0 -9
  602. package/dist/chunks/studio-g5fmf0c1.js +0 -5
  603. package/dist/chunks/studio-g7nse7zb.js +0 -5
  604. package/dist/chunks/studio-geq1ea6k.js +0 -14
  605. package/dist/chunks/studio-ghkb32r8.js +0 -5
  606. package/dist/chunks/studio-ghrhy2y7.js +0 -5
  607. package/dist/chunks/studio-grawhey1.js +0 -5
  608. package/dist/chunks/studio-h0xgswew.js +0 -5
  609. package/dist/chunks/studio-h9c4p2tx.js +0 -5
  610. package/dist/chunks/studio-jyzj5cxs.js +0 -5
  611. package/dist/chunks/studio-mgx8yhnz.js +0 -64
  612. package/dist/chunks/studio-mpb04y1d.js +0 -6
  613. package/dist/chunks/studio-n17mty64.js +0 -5
  614. package/dist/chunks/studio-nwh2eqsk.js +0 -6
  615. package/dist/chunks/studio-q1h883bt.js +0 -16
  616. package/dist/chunks/studio-q4tv82h7.js +0 -9
  617. package/dist/chunks/studio-qpqa7vk3.js +0 -5
  618. package/dist/chunks/studio-qqz8e5gk.js +0 -5
  619. package/dist/chunks/studio-qvasen3f.js +0 -5
  620. package/dist/chunks/studio-rggdb3hm.js +0 -5
  621. package/dist/chunks/studio-sghy936h.js +0 -4
  622. package/dist/chunks/studio-skprc6ef.js +0 -5
  623. package/dist/chunks/studio-tt2nactf.js +0 -5
  624. package/dist/chunks/studio-tyasmc39.js +0 -5
  625. package/dist/chunks/studio-vk9ezads.js +0 -5
  626. package/dist/chunks/studio-vzacdfsc.js +0 -4
  627. package/dist/chunks/studio-w4c0xmrw.js +0 -5
  628. package/dist/chunks/studio-wfjqhhbk.js +0 -5
  629. package/dist/chunks/studio-wgh5kxpj.js +0 -5
  630. package/dist/chunks/studio-xasj0796.js +0 -5
  631. package/dist/chunks/studio-y78s8r2n.js +0 -5
  632. package/dist/chunks/studio-z8w183sh.js +0 -5
  633. package/dist/chunks/studio-zscd9ty4.js +0 -928
  634. package/dist/chunks/studio-zxp13sss.js +0 -7
  635. package/dist/chunks/studio-zygnmm01.js +0 -5
  636. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  637. package/dist/chunks/tabs-jwthg40w.js +0 -4
  638. package/dist/chunks/textfield-spy3hc77.js +0 -4
  639. package/dist/chunks/toast-4d35zd64.js +0 -4
  640. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  641. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  642. package/dist/chunks/tree-h19v1jfz.js +0 -4
  643. package/dist/chunks/tsMode-gr0m4dzr.js +0 -14
  644. package/dist/chunks/workspace-m15qtcqp.js +0 -4
  645. package/dist/chunks/ws-client-nf61frr1.js +0 -4
@@ -2,29 +2,30 @@
2
2
  * Ai-command-tools.ts — the assistant's tools that ARE command records.
3
3
  *
4
4
  * A `ToolRegistry` that is a VIEW over this window's active command registry, in the idiom of
5
- * `services/automation.ts`'s `scriptableCommands()`: nothing is registered here, ever. Every call to
6
- * `listForLLM()` enumerates the records that carry an `aiTool` projection and builds one function
7
- * schema per record whose `parameters` is the record's own `args` object — by reference, so a
8
- * `derivedEnumProperty` getter serialises live on every agent-loop round — whose `description` is
9
- * the record's, and which is advertised exactly while `registry.isEnabled(id)` holds. `execute` is
10
- * `registry.run(id, args)`.
5
+ * `services/automation.ts`'s `scriptableCommands()`: nothing is registered here, ever. Every call
6
+ * to `listForLLM()` enumerates the records that carry an `aiTool` projection and builds one
7
+ * function schema per record whose `parameters` is the record's own `args` object — by reference,
8
+ * so a `derivedEnumProperty` getter serialises live on every agent-loop round — whose `description`
9
+ * is the record's, and which is advertised exactly while `registry.isEnabled(id)` holds. `execute`
10
+ * is `registry.run(id, args)`.
11
11
  *
12
12
  * **Why a view and not a registration.** `const assistant = createDocumentAssistant()` runs at
13
13
  * module load of `panels/ai-panel.ts`, before the bootstrap composes the registry, so a
14
14
  * registration step would have to import `app-commands.ts` (every command module into the
15
- * assistant's import graph) and read `report` from a record built with `noopCommandDeps` — a
16
- * second instance of every record, whose closures are not the app's. A view has neither problem,
17
- * and it cannot be dormant: issue 273 was forty-seven declarations that reached the assistant from
18
- * none of them, because each waited on a hand-registered tool nobody wrote. There is no
19
- * registration step between `aiTool` and the tool, so there is nothing to omit.
15
+ * assistant's import graph) and read `report` from a record built with `noopCommandDeps` — a second
16
+ * instance of every record, whose closures are not the app's. A view has neither problem, and it
17
+ * cannot be dormant: issue 273 was forty-seven declarations that reached the assistant from none of
18
+ * them, because each waited on a hand-registered tool nobody wrote. There is no registration step
19
+ * between `aiTool` and the tool, so there is nothing to omit.
20
20
  *
21
- * **What the model reads.** A refusal is the person's own sentence: `CommandUnavailableError.message`
22
- * IS `refusalSentence`, and a `RangeError` from `coerceArgs` (which `registry.run` applies for
23
- * every caller) or from inside `run` already names the value and the declared list. Both pass
24
- * through untouched. There is deliberately no pre-check with `refusalMessage` — `run` refuses with
25
- * the same sentence, and a second call site for one predicate is precisely the divergence
26
- * `specs/studio-ui-guidelines.md` §12.4 is about. And because this module owns `execute`,
27
- * `@jxsuite/ai`'s `Tool "<name>" execution error:` prefix never wraps a refusal.
21
+ * **What the model reads.** A refusal is the person's own sentence:
22
+ * `CommandUnavailableError.message` IS `refusalSentence`, and a `RangeError` from `coerceArgs`
23
+ * (which `registry.run` applies for every caller) or from inside `run` already names the value and
24
+ * the declared list. Both pass through untouched. There is deliberately no pre-check with
25
+ * `refusalMessage` — `run` refuses with the same sentence, and a second call site for one predicate
26
+ * is precisely the divergence `specs/studio-ui-guidelines.md` §12.4 is about. And because this
27
+ * module owns `execute`, `@jxsuite/ai`'s `Tool "<name>" execution error:` prefix never wraps a
28
+ * refusal.
28
29
  *
29
30
  * **The write witness.** A record with `undo: "document"` is held to having written: `transactDoc`
30
31
  * replaces the document's root reference on every applied transaction (`tabs/transact.ts`), so an
@@ -36,11 +37,11 @@
36
37
  * a transaction on the configuration document (`tabs/project-config.ts`), whose bind effect keeps
37
38
  * `projectState.projectConfig` equal to `toRaw(document.doc.document)` — so a record with `undo:
38
39
  * "project"` that left that reference alone wrote nothing, whatever its report says. The ledger
39
- * then files nothing (`wrote: []`, mechanically, for every project record), and a report that
40
- * named no `wrote` of its own — one with no latch to know it was a no-op — has its sentence
41
- * replaced by "changed nothing", because "Wrote project.json" over an untouched file is the
42
- * phantom the ledger exists to keep out. A record whose report answered `wrote: []` itself is one
43
- * that KNEW, and its sentence ("already enabled") is the one the witness cannot write. That is why
40
+ * then files nothing (`wrote: []`, mechanically, for every project record), and a report that named
41
+ * no `wrote` of its own — one with no latch to know it was a no-op — has its sentence replaced by
42
+ * "changed nothing", because "Wrote project.json" over an untouched file is the phantom the ledger
43
+ * exists to keep out. A record whose report answered `wrote: []` itself is one that KNEW, and its
44
+ * sentence ("already enabled") is the one the witness cannot write. That is why
44
45
  * `add_project_locale` keeps its latch: the sentence, not the ledger, is what the latch is for.
45
46
  *
46
47
  * **A tool with nothing it could be called with is withheld.** A `derivedEnumProperty` on a
@@ -52,8 +53,8 @@
52
53
  * the coercion's own refusal (`is not declared — declared: none`) rather than `Unknown tool`.
53
54
  *
54
55
  * **`validate()` is a no-op, on purpose.** `@jxsuite/ai`'s validator never checks `enum` and treats
55
- * a required `null` as missing (`packages/ai/src/tools.ts`), which would refuse `select_node
56
- * { path: null }`. The registry's coercion is the single validator, so every projected tool is
56
+ * a required `null` as missing (`packages/ai/src/tools.ts`), which would refuse `select_node {
57
+ * path: null }`. The registry's coercion is the single validator, so every projected tool is
57
58
  * `strict: false`.
58
59
  *
59
60
  * @license MIT
@@ -61,14 +62,18 @@
61
62
 
62
63
  import { createToolContext, toolError } from "@jxsuite/ai/tools";
63
64
  import type {
65
+ ToolArguments,
64
66
  ToolContext,
65
67
  ToolDefinition,
66
68
  ToolRegistry,
67
69
  ToolResult,
68
70
  WriteLedger,
69
71
  } from "@jxsuite/ai/tools";
72
+ import { isString } from "@jxsuite/schema/guards";
73
+ import type { ProjectConfig } from "@jxsuite/schema/types";
70
74
  import { activeRegistry } from "../commands/active-registry";
71
75
  import { argsSchema } from "../commands/command-args";
76
+ import type { CommandArgsSchema, PropertySchema } from "../commands/command-args";
72
77
  import { inCanvas } from "../commands/context";
73
78
  import { toRaw } from "../reactivity";
74
79
  import { projectState } from "../state";
@@ -99,12 +104,6 @@ export interface CommandToolDeps extends WriteReportDeps {
99
104
  /** Schema for a record that declares no `args`: an empty object, so the wire shape is uniform. */
100
105
  const EMPTY_ARGS = argsSchema({});
101
106
 
102
- /** The loosely-typed view of a record's `args` this module reads. */
103
- interface ArgsShape {
104
- properties?: Record<string, { enum?: unknown }>;
105
- required?: readonly string[];
106
- }
107
-
108
107
  /**
109
108
  * Whether a required argument's choice list is empty right now.
110
109
  *
@@ -112,10 +111,10 @@ interface ArgsShape {
112
111
  * runs on the wire — so this is the same answer the model would have been shown. Only a REQUIRED
113
112
  * property counts: an optional enum that is empty is an argument the model can leave out.
114
113
  */
115
- function hasEmptyRequiredEnum(args: object | undefined): boolean {
116
- const shape = (args ?? EMPTY_ARGS) as ArgsShape;
117
- return (shape.required ?? []).some((key) => {
118
- const declared = shape.properties?.[key]?.enum;
114
+ function hasEmptyRequiredEnum(args: CommandArgsSchema | undefined): boolean {
115
+ const view = args ?? EMPTY_ARGS;
116
+ return (view.required ?? []).some((key) => {
117
+ const declared = view.properties?.[key]?.enum;
119
118
  return Array.isArray(declared) && declared.length === 0;
120
119
  });
121
120
  }
@@ -125,9 +124,8 @@ function hasEmptyRequiredEnum(args: object | undefined): boolean {
125
124
  * description the model reads is the selector's. `undefined` when the selector is not registered,
126
125
  * in which case no selection-level record can be composed and none is projected.
127
126
  */
128
- function pathsProperty(registry: CommandRegistry): object | undefined {
129
- const args = registry.get(SELECTOR)?.args as ArgsShape | undefined;
130
- return args?.properties?.paths;
127
+ function pathsProperty(registry: CommandRegistry): PropertySchema | undefined {
128
+ return registry.get(SELECTOR)?.args?.properties?.paths;
131
129
  }
132
130
 
133
131
  /**
@@ -136,8 +134,8 @@ function pathsProperty(registry: CommandRegistry): object | undefined {
136
134
  * selection verb with an argument of its own compose without a rule change — and `register()`
137
135
  * refuses a selection-level record that declares `paths` itself, so the two cannot collide.
138
136
  */
139
- function withPaths(paths: object, args: object | undefined): object {
140
- const own = (args ?? EMPTY_ARGS) as ArgsShape;
137
+ function withPaths(paths: PropertySchema, args: CommandArgsSchema | undefined): CommandArgsSchema {
138
+ const own = args ?? EMPTY_ARGS;
141
139
  return {
142
140
  additionalProperties: false,
143
141
  properties: { paths, ...own.properties },
@@ -203,10 +201,10 @@ function projected(registry: CommandRegistry): AnyCommand[] {
203
201
  function definitionOf(
204
202
  registry: CommandRegistry,
205
203
  command: AnyCommand,
206
- execute: (name: string, args: object, ctx: ToolContext) => Promise<ToolResult>,
204
+ execute: (name: string, args: ToolArguments, ctx: ToolContext) => Promise<ToolResult>,
207
205
  ): ToolDefinition | undefined {
208
206
  const tool = command.aiTool!;
209
- let parameters: object;
207
+ let parameters: CommandArgsSchema;
210
208
  if (command.level === "selection") {
211
209
  const paths = pathsProperty(registry);
212
210
  if (paths === undefined) {
@@ -219,6 +217,11 @@ function definitionOf(
219
217
  return {
220
218
  name: tool.name,
221
219
  description: `${tool.description}${undoSuffix(command)}`,
220
+ /* SAFETY: `parameters` is an `argsSchema()` object (or the selector's composed from one), a
221
+ JSON Schema object whose only departures from `JSONSchema` are readonly arrays and a
222
+ property `type` that may be a list — neither of which the registry's validator ever reads,
223
+ because every projected tool is `strict: false`. It is passed by reference so a
224
+ `derivedEnumProperty` getter still serialises live on the wire. */
222
225
  parameters: parameters as ToolDefinition["parameters"],
223
226
  strict: false,
224
227
  llmStrict: false,
@@ -233,15 +236,16 @@ function definitionOf(
233
236
  * what the gate will honour — one function, not two that agree until someone edits one.
234
237
  *
235
238
  * @param {CommandRegistry} registry
236
- * @param {(name: string, args: object) => Promise<ToolResult>} [execute] What each definition's
237
- * `execute` calls. Defaults to a refusal, so a caller that only reads definitions cannot run
238
- * one.
239
+ * @param {(name: string, args: ToolArguments) => Promise<ToolResult>} [execute] What each
240
+ * definition's `execute` calls. Defaults to a refusal, so a caller that only reads definitions
241
+ * cannot run one.
239
242
  * @returns {ToolDefinition[]}
240
243
  */
241
244
  export function advertisedCommandTools(
242
245
  registry: CommandRegistry,
243
- execute: (name: string, args: object, ctx: ToolContext) => Promise<ToolResult> = async (name) =>
244
- toolError(`Tool "${name}" was listed without an executor.`),
246
+ execute: (name: string, args: ToolArguments, ctx: ToolContext) => Promise<ToolResult> = async (
247
+ name,
248
+ ) => toolError(`Tool "${name}" was listed without an executor.`),
245
249
  ): ToolDefinition[] {
246
250
  const definitions: ToolDefinition[] = [];
247
251
  for (const command of projected(registry)) {
@@ -257,10 +261,9 @@ export function advertisedCommandTools(
257
261
  }
258
262
 
259
263
  /** The parameter list a prompt blurb prints: `a, b?` — required names bare, optional ones marked. */
260
- function signatureOf(parameters: object): string {
261
- const shape = parameters as ArgsShape;
262
- const required = new Set(shape.required);
263
- return Object.keys(shape.properties ?? {})
264
+ function signatureOf(parameters: ToolDefinition["parameters"]): string {
265
+ const required = new Set(parameters.required);
266
+ return Object.keys(parameters.properties ?? {})
264
267
  .map((key) => (required.has(key) ? key : `${key}?`))
265
268
  .join(", ");
266
269
  }
@@ -290,7 +293,7 @@ export function commandToolBlurbs(registry: CommandRegistry | null): string[] {
290
293
 
291
294
  /** A `report` return, normalised: a bare string is a summary alone. */
292
295
  function normaliseReport(report: string | AiToolReport): AiToolReport {
293
- return typeof report === "string" ? { summary: report } : report;
296
+ return isString(report) ? { summary: report } : report;
294
297
  }
295
298
 
296
299
  /**
@@ -301,9 +304,9 @@ function normaliseReport(report: string | AiToolReport): AiToolReport {
301
304
  * configuration document is a new reference here — and an unchanged reference is a run that never
302
305
  * transacted, however the record's report reads.
303
306
  */
304
- function projectConfigRef(): object | null {
307
+ function projectConfigRef(): ProjectConfig | null {
305
308
  const config = projectState?.projectConfig;
306
- return config ? toRaw(config as unknown as object) : null;
309
+ return config ? toRaw(config) : null;
307
310
  }
308
311
 
309
312
  /**
@@ -362,12 +365,12 @@ export function createCommandToolRegistry(deps: CommandToolDeps): ToolRegistry {
362
365
  * Run one projected record as the agent — the whole of `ai.md` §3.6.
363
366
  *
364
367
  * @param {string} name
365
- * @param {object} received
368
+ * @param {ToolArguments} args
366
369
  * @returns {Promise<ToolResult>}
367
370
  */
368
371
  async function execute(
369
372
  name: string,
370
- received: object,
373
+ args: ToolArguments,
371
374
  ctx: ToolContext = createToolContext(),
372
375
  ): Promise<ToolResult> {
373
376
  const registry = activeRegistry();
@@ -380,7 +383,6 @@ export function createCommandToolRegistry(deps: CommandToolDeps): ToolRegistry {
380
383
  : { error: `Cannot run "${name}" — this window has no command registry.`, success: false };
381
384
  }
382
385
  const tool = command.aiTool!;
383
- const args = received as Record<string, unknown>;
384
386
 
385
387
  /* The witness and the snapshot, only for a record that writes the document: `rootBefore` is
386
388
  what `transactDoc` replaces, and the snapshot is what the verdict compares against. */
@@ -434,6 +436,10 @@ export function createCommandToolRegistry(deps: CommandToolDeps): ToolRegistry {
434
436
  const after = registry.context();
435
437
  let report: AiToolReport;
436
438
  try {
439
+ /* SAFETY: `AnyCommand` erases the record's argument type to `never` (see its declaration), so
440
+ `report` cannot be called without one assertion. Every key here was just accepted by
441
+ `registry.run` — `paths` by the selector, the rest by this record's own `coerceArgs` pass
442
+ against its `args` schema — and a refusal threw into the catch above, which returned. */
437
443
  report = normaliseReport(tool.report({ after, args: args as never, before }));
438
444
  } catch (error) {
439
445
  /* `run` has resolved, so the write HAPPENED; a report that throws must not make it vanish.
@@ -465,11 +471,11 @@ export function createCommandToolRegistry(deps: CommandToolDeps): ToolRegistry {
465
471
  /* A success verdict may have appended the token hints; the report's sentence is kept. */
466
472
  summary = verdict.summary ?? summary;
467
473
  }
468
- return {
469
- success: true,
470
- summary,
471
- ...(report.data === undefined ? {} : { data: report.data }),
472
- };
474
+ const result: ToolResult = { success: true, summary };
475
+ if (report.data !== undefined) {
476
+ result.data = report.data;
477
+ }
478
+ return result;
473
479
  }
474
480
 
475
481
  return {
@@ -1,19 +1,18 @@
1
1
  /**
2
2
  * Ai-import-tools.ts — `import_site`, the assistant's other way to bootstrap a project.
3
3
  *
4
- * A sibling of `create_project` (`ai-project-tools.ts`) with a different backend: it drives whatever
5
- * import pipeline the platform's `importSite` reaches — a local headless Chrome, or a hosted one —
6
- * streams its progress into a record the transcript draws, and then adopts the result exactly as a
7
- * scaffold is adopted. Its own module
8
- * rather than an eighth tool in `ai-project-tools.ts`, which is already 650 lines under a per-file
9
- * coverage bar.
4
+ * A sibling of `create_project` (`ai-project-tools.ts`) with a different backend: it drives
5
+ * whatever import pipeline the platform's `importSite` reaches — a local headless Chrome, or a
6
+ * hosted one — streams its progress into a record the transcript draws, and then adopts the result
7
+ * exactly as a scaffold is adopted. Its own module rather than an eighth tool in
8
+ * `ai-project-tools.ts`, which is already 650 lines under a per-file coverage bar.
10
9
  *
11
10
  * Two things it does NOT do are the point:
12
11
  *
13
12
  * - **It does not invent a destination.** `create_project` requires the model to supply `location`
14
13
  * and refuses without one — correct when a bare chat bootstraps a project, a regression on the
15
- * wizard path where the Location field already has a folder picker, validation and a live preview.
16
- * The destination comes from the pending brief; a model-supplied one must match it.
14
+ * wizard path where the Location field already has a folder picker, validation and a live
15
+ * preview. The destination comes from the pending brief; a model-supplied one must match it.
17
16
  * - **It does not decide what the crawl found.** The pipeline is one-way: it reports and finishes.
18
17
  * Everything worth a human's opinion — which skipped pages matter, whether the components it
19
18
  * extracted are really components — is in the summary for the model to raise with `ask_user`
@@ -23,23 +22,26 @@
23
22
  */
24
23
 
25
24
  import { createToolDefinition, toolError, toolSuccess } from "@jxsuite/ai/tools";
25
+ import { IMPORT_MAX_PAGES } from "@jxsuite/protocol";
26
+ import { isBoolean, isNumber, isString } from "@jxsuite/schema/guards";
26
27
  import { getPlatform } from "../platform";
27
28
  import { workspace } from "../workspace/workspace";
28
29
  import { getBaseUrl, getOpenAiKey } from "./ai-settings";
29
30
  import { preferredModel } from "./ai-models";
30
- import { clearPendingImportBrief, pendingImportBrief } from "./import-seed";
31
+ import { MAX_IMPORT_DEPTH, clearPendingImportBrief, pendingImportBrief } from "./import-seed";
31
32
  import type { ImportBrief } from "./import-seed";
32
33
  import { abortImportRun, beginImportRun, finishImportRun, importRun } from "./import-run";
33
34
  import { adoptCreatedProject } from "./project-adoption";
34
- import type { AdoptOutcome } from "./project-adoption";
35
+ import type { AdoptCreatedOptions, AdoptOutcome } from "./project-adoption";
35
36
 
36
37
  import type { JsonValue, ToolRegistry } from "@jxsuite/ai/tools";
37
38
  import type { Tab } from "../tabs/tab";
38
- import type { ImportBreakpointPolicy, ImportReadyEvent, ImportSiteSummary } from "../types";
39
-
40
- /** The same bounds `packages/server/src/import-api.ts` clamps to. */
41
- const MAX_DEPTH = 5;
42
- const MAX_PAGES = 100;
39
+ import type {
40
+ ImportBreakpointPolicy,
41
+ ImportReadyEvent,
42
+ ImportSiteOptions,
43
+ ImportSiteSummary,
44
+ } from "../types";
43
45
 
44
46
  /** Log lines quoted back on a hard failure — enough to see WHICH phase died. */
45
47
  const FAILURE_TAIL = 5;
@@ -73,6 +75,15 @@ export interface ImportToolsCtx {
73
75
  brief?: { read: () => ImportBrief | null; clear: () => void };
74
76
  }
75
77
 
78
+ /**
79
+ * The adoption a `ready` line started, if one did. A holder rather than a `let`, because the
80
+ * assignment happens inside the `onReady` callback and control-flow analysis cannot see it: a plain
81
+ * `let` reads as always-`null` after the run.
82
+ */
83
+ interface EarlyAdoption {
84
+ pending: Promise<AdoptOutcome> | null;
85
+ }
86
+
76
87
  function clamp(value: number, min: number, max: number): number {
77
88
  return Math.min(max, Math.max(min, Math.trunc(value)));
78
89
  }
@@ -89,7 +100,11 @@ function clamp(value: number, min: number, max: number): number {
89
100
  * @returns {ImportBreakpointPolicy | undefined}
90
101
  */
91
102
  function breakpointPolicyFor(
92
- args: { maxBreakpoints?: unknown; widths?: unknown; rounding?: unknown },
103
+ args: {
104
+ maxBreakpoints: JsonValue | undefined;
105
+ widths: JsonValue | undefined;
106
+ rounding: JsonValue | undefined;
107
+ },
93
108
  fromBrief: ImportBreakpointPolicy | undefined,
94
109
  ): ImportBreakpointPolicy | undefined {
95
110
  const rounding =
@@ -100,7 +115,7 @@ function breakpointPolicyFor(
100
115
  if (Array.isArray(args.widths) && args.widths.length > 0) {
101
116
  return { mode: "explicit", rounding, widths: args.widths.map(Number) };
102
117
  }
103
- if (typeof args.maxBreakpoints === "number" && Number.isFinite(args.maxBreakpoints)) {
118
+ if (isNumber(args.maxBreakpoints) && Number.isFinite(args.maxBreakpoints)) {
104
119
  // Zero is the only spelling a count has for "keep all", and it is worth accepting: it is what
105
120
  // A model reaches for when a person says "keep them all".
106
121
  return args.maxBreakpoints <= 0
@@ -346,18 +361,7 @@ export function registerImportTools(
346
361
  maxBreakpoints,
347
362
  breakpointWidths,
348
363
  breakpointRounding,
349
- } = args as {
350
- url?: unknown;
351
- directory?: unknown;
352
- depth?: unknown;
353
- maxPages?: unknown;
354
- aiComponents?: unknown;
355
- verify?: unknown;
356
- minFidelity?: unknown;
357
- maxBreakpoints?: unknown;
358
- breakpointWidths?: unknown;
359
- breakpointRounding?: unknown;
360
- };
364
+ } = args;
361
365
 
362
366
  if (workspace.projectRoot) {
363
367
  return toolError(
@@ -386,7 +390,7 @@ export function registerImportTools(
386
390
  }
387
391
 
388
392
  const brief = briefStore.read();
389
- const requested = typeof directory === "string" ? directory.trim() : "";
393
+ const requested = isString(directory) ? directory.trim() : "";
390
394
  if (requested && brief && requested !== brief.directory) {
391
395
  /* The wizard's Location field is the user's answer to "where does this go". A model that
392
396
  disagrees with it is guessing at a decision that was already made in front of them. */
@@ -450,44 +454,56 @@ export function registerImportTools(
450
454
  * failure here is not the run's failure: the import continues either way, and the terminal
451
455
  * path below reports honestly on whichever state the window ended up in.
452
456
  */
453
- let adoption: Promise<AdoptOutcome> | null = null;
457
+ const adoptOptions: AdoptCreatedOptions = { getTab };
458
+ if (adoptProject) {
459
+ adoptOptions.adopt = adoptProject;
460
+ }
461
+ const early: EarlyAdoption = { pending: null };
454
462
  const onReady = ({ root }: ImportReadyEvent) => {
455
- adoption ??= adoptCreatedProject(root, {
456
- getTab,
457
- ...(adoptProject ? { adopt: adoptProject } : {}),
458
- });
463
+ early.pending ??= adoptCreatedProject(root, adoptOptions);
464
+ };
465
+
466
+ const options: ImportSiteOptions = {
467
+ aiComponents: isBoolean(aiComponents) ? aiComponents : (brief?.aiComponents ?? true),
468
+ depth: clamp(Number(depth ?? brief?.depth ?? 1) || 0, 0, MAX_IMPORT_DEPTH),
469
+ directory: destination,
470
+ maxPages: clamp(Number(maxPages ?? brief?.maxPages ?? 20) || 1, 1, IMPORT_MAX_PAGES),
471
+ name: brief?.name || target.hostname.replace(/^www\./, ""),
472
+ url: target.href,
459
473
  };
474
+ if (breakpoints !== undefined) {
475
+ options.breakpoints = breakpoints;
476
+ }
477
+ if (isBoolean(verify)) {
478
+ options.verify = verify;
479
+ } else if (brief?.verify !== undefined) {
480
+ options.verify = brief.verify;
481
+ }
482
+ /* The wizard's number is the user's own answer to "how close is close enough"; the model
483
+ may only override it when it was told to. */
484
+ options.verifyMinFidelity = clamp(
485
+ Number(minFidelity ?? brief?.minFidelity ?? DEFAULT_MIN_FIDELITY) || 0,
486
+ 0,
487
+ MAX_FIDELITY,
488
+ );
489
+ if (apiKey) {
490
+ options.apiKey = apiKey;
491
+ }
492
+ if (baseUrl) {
493
+ options.baseUrl = baseUrl;
494
+ }
495
+ if (model) {
496
+ options.model = model;
497
+ }
460
498
 
461
499
  let result: { root: string; result?: ImportSiteSummary };
462
500
  try {
463
501
  result = await platform.importSite(
464
- {
465
- aiComponents:
466
- typeof aiComponents === "boolean" ? aiComponents : (brief?.aiComponents ?? true),
467
- depth: clamp(Number(depth ?? brief?.depth ?? 1) || 0, 0, MAX_DEPTH),
468
- directory: destination,
469
- maxPages: clamp(Number(maxPages ?? brief?.maxPages ?? 20) || 1, 1, MAX_PAGES),
470
- name: brief?.name || target.hostname.replace(/^www\./, ""),
471
- url: target.href,
472
- ...(breakpoints === undefined ? {} : { breakpoints }),
473
- ...(typeof verify === "boolean"
474
- ? { verify }
475
- : brief?.verify === undefined
476
- ? {}
477
- : { verify: brief.verify }),
478
- /* The wizard's number is the user's own answer to "how close is close enough"; the
479
- model may only override it when it was told to. */
480
- verifyMinFidelity: clamp(
481
- Number(minFidelity ?? brief?.minFidelity ?? DEFAULT_MIN_FIDELITY) || 0,
482
- 0,
483
- MAX_FIDELITY,
484
- ),
485
- ...(apiKey ? { apiKey } : {}),
486
- ...(baseUrl ? { baseUrl } : {}),
487
- ...(model ? { model } : {}),
488
- },
502
+ options,
489
503
  (evt) => {
490
- ctx.progress(evt as unknown as JsonValue);
504
+ /* The spread is the event's own fields as an object literal, which TypeScript lets
505
+ stand as a JSON object where the named interface cannot. */
506
+ ctx.progress({ ...evt });
491
507
  },
492
508
  signal,
493
509
  onReady,
@@ -522,15 +538,12 @@ export function registerImportTools(
522
538
 
523
539
  /* The early adoption if there was one, otherwise adopt now: a backend that sends no `ready`
524
540
  line is not broken, it is older, and the project must still open. */
525
- const { adopted, error: adoptionError } = await (adoption ??
526
- adoptCreatedProject(result.root, {
527
- getTab,
528
- ...(adoptProject ? { adopt: adoptProject } : {}),
529
- }));
541
+ const { adopted, error: adoptionError } = await (early.pending ??
542
+ adoptCreatedProject(result.root, adoptOptions));
530
543
  if (adopted) {
531
544
  onProjectAdopted?.(result.root);
532
545
  return toolSuccess(
533
- { root: result.root, ...(result.result ? { summary: result.result } : {}) },
546
+ result.result ? { root: result.root, summary: result.result } : { root: result.root },
534
547
  describeRun(id, result.root, result.result),
535
548
  );
536
549
  }
@@ -10,7 +10,9 @@
10
10
  * @license MIT
11
11
  */
12
12
 
13
+ import type { AiCredentials } from "@jxsuite/ai/streaming-client";
13
14
  import type { AiModelsResponse, OfferedAction } from "@jxsuite/protocol";
15
+ import { isBoolean, isNumber, isString } from "@jxsuite/schema/guards";
14
16
  import { getPlatform } from "../platform";
15
17
  import { offeredActions } from "../platform-errors";
16
18
  import { getBaseUrl, getOpenAiKey, hasOpenAiKey, storedModel } from "./ai-settings";
@@ -38,10 +40,7 @@ export interface AiModel {
38
40
  * Two fields, taken together or not at all. The per-field overrides this replaces let a caller pass
39
41
  * a draft key with a stored base URL, which is a pair that was never configured anywhere.
40
42
  */
41
- export interface AiCredentials {
42
- apiKey: string;
43
- baseUrl: string;
44
- }
43
+ export type { AiCredentials } from "@jxsuite/ai/streaming-client";
45
44
 
46
45
  /** The credentials the app is configured with right now. */
47
46
  export function aiConnection(): AiCredentials {
@@ -380,19 +379,24 @@ export async function fetchAvailableModels(
380
379
  if (!resp.ok) {
381
380
  throw new Error(`HTTP ${resp.status}`);
382
381
  }
382
+ /* SAFETY: this route is served by a Studio backend answering with `AiModelsResponse`
383
+ (`@jxsuite/protocol`); `Partial` because an older backend omits members. The members that
384
+ decide a gate (`configured`, `managed`, `code`, `detail`, a model's capabilities) are each
385
+ compared to a literal or guarded below before use; the rest are passed through as display text. */
383
386
  const data = (await resp.json()) as Partial<AiModelsResponse>;
384
387
  proxyConfigured = data.configured === true;
385
388
  proxyManaged = data.managed === true;
386
389
  proxyDefaultModel = data.defaultModel ?? "";
387
390
  proxyCode = data.code;
388
391
  proxyModelsError = data.upstreamError !== undefined ? (data.upstreamMessage ?? "") : "";
389
- proxyAction =
390
- data.code === "action_required"
391
- ? {
392
- actions: offeredActions(data.actions),
393
- ...(typeof data.detail === "string" && data.detail ? { detail: data.detail } : {}),
394
- }
395
- : null;
392
+ proxyAction = null;
393
+ if (data.code === "action_required") {
394
+ const offer: ProxyActionOffer = { actions: offeredActions(data.actions) };
395
+ if (isString(data.detail) && data.detail) {
396
+ offer.detail = data.detail;
397
+ }
398
+ proxyAction = offer;
399
+ }
396
400
  /* Capabilities are kept, not dropped. The backend has reported `toolSupport` all along and the
397
401
  ingest mapped `{id, name}` only, so a Workers AI model that cannot call tools looked exactly
398
402
  like one that can — the agent loop ran, called nothing, and answered as if that were normal.
@@ -400,10 +404,10 @@ export async function fetchAvailableModels(
400
404
  which is a third state both consumers depend on. */
401
405
  cache = (data.models || []).map((m) => {
402
406
  const model: AiModel = { id: m.id, name: m.name || m.id };
403
- if (typeof m.contextWindow === "number") {
407
+ if (isNumber(m.contextWindow)) {
404
408
  model.contextWindow = m.contextWindow;
405
409
  }
406
- if (typeof m.toolSupport === "boolean") {
410
+ if (isBoolean(m.toolSupport)) {
407
411
  model.toolSupport = m.toolSupport;
408
412
  }
409
413
  return model;