@jxsuite/studio 5.0.0 → 5.2.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 (132) hide show
  1. package/dist/chunks/{cf-account-picker-fyf63pmy.js → cf-account-picker-h4dab9bq.js} +10 -10
  2. package/dist/chunks/{cf-settings-71bv5zn9.js → cf-settings-adg74qsk.js} +4 -4
  3. package/dist/chunks/components-5y78e05d.js +20 -0
  4. package/dist/chunks/content-source-sgg1sv6n.js +46 -0
  5. package/dist/chunks/{convert-to-repeater-d0cgnb6d.js → convert-to-repeater-mf1cxgfn.js} +25 -25
  6. package/dist/chunks/entry-commands-w9qsxa6q.js +42 -0
  7. package/dist/chunks/{extension-sections-fy7q4fe9.js → extension-sections-c6zwzbre.js} +27 -27
  8. package/dist/chunks/file-ops-vrpq1jjk.js +47 -0
  9. package/dist/chunks/{files-ef8fgs3w.js → files-msaf95y6.js} +33 -32
  10. package/dist/chunks/{format-host-3c33nwr8.js → format-host-f64fnesp.js} +2 -2
  11. package/dist/chunks/{fs-events-13tj6sex.js → fs-events-3y6y0nrm.js} +6 -6
  12. package/dist/chunks/git-panel-bv5e22j0.js +50 -0
  13. package/dist/chunks/grid-view-1p6hsyjx.css +8406 -0
  14. package/dist/chunks/grid-view-paj67nr5.js +15322 -0
  15. package/dist/chunks/{iframe-host-jgesd924.js → iframe-host-dh5np8vk.js} +14 -14
  16. package/dist/chunks/{layers-1nq5evsh.js → layers-1vcfdbet.js} +7 -6
  17. package/dist/chunks/layers-panel-fksbdg4q.js +40 -0
  18. package/dist/chunks/{media-picker-2qbetq73.js → media-picker-p49nhqhs.js} +14 -14
  19. package/dist/chunks/menu-qht48vnc.js +15 -0
  20. package/dist/chunks/{monaco-buffer-bhy3hb6m.js → monaco-buffer-pykwbm92.js} +3 -3
  21. package/dist/chunks/{notify-628t0anh.js → notify-42gk8ha1.js} +2 -2
  22. package/dist/chunks/{parse-0zx14y15.js → parse-reg9eevt.js} +2 -2
  23. package/dist/chunks/publish-panel-vz23wwmg.js +27 -0
  24. package/dist/chunks/quick-search-e9rp74m8.js +46 -0
  25. package/dist/chunks/{references-n553f0e1.js → references-h69xp9zz.js} +4 -4
  26. package/dist/chunks/right-panel-j97t2yvy.js +45 -0
  27. package/dist/chunks/{studio-18avnhjp.js → studio-01jeck2y.js} +36 -30
  28. package/dist/chunks/{studio-9xxz1q69.js → studio-14d9tq4d.js} +9 -9
  29. package/dist/chunks/{studio-xsykpvsh.js → studio-15f3kxqe.js} +19 -19
  30. package/dist/chunks/studio-1tbjfqv4.js +146 -0
  31. package/dist/chunks/{studio-79y5sz51.js → studio-28vs5k2y.js} +2 -2
  32. package/dist/chunks/{studio-3hxkd92t.js → studio-2mdbbc76.js} +10 -10
  33. package/dist/chunks/{studio-7r42c6ca.js → studio-3ntvq6cg.js} +5 -5
  34. package/dist/chunks/{studio-8jn5yhyn.js → studio-4c041r8y.js} +3 -3
  35. package/dist/chunks/{studio-qahxvnan.js → studio-4r14yzyy.js} +4 -4
  36. package/dist/chunks/{studio-arfpe389.js → studio-4xmjcrg3.js} +6 -6
  37. package/dist/chunks/{studio-5523bpzt.js → studio-5nz00bhh.js} +3 -3
  38. package/dist/chunks/{studio-x3rty6tr.js → studio-5t7ena5z.js} +8 -8
  39. package/dist/chunks/{studio-5rt7sqa0.js → studio-66arbpc2.js} +13 -19
  40. package/dist/chunks/{studio-fabxk6r9.js → studio-68fydsrj.js} +15 -15
  41. package/dist/chunks/{studio-tb3ev01j.js → studio-9j6sfeba.js} +6 -6
  42. package/dist/chunks/{studio-akbww0j5.js → studio-a1pswps3.js} +38 -38
  43. package/dist/chunks/{studio-6xa21ej9.js → studio-c04nzbby.js} +2 -2
  44. package/dist/chunks/{studio-4m0haseg.js → studio-c07s5ckd.js} +4 -4
  45. package/dist/chunks/{studio-57mf66w2.js → studio-ctm7bhx5.js} +14 -14
  46. package/dist/chunks/{studio-p1dw8wfw.js → studio-d8z5bajd.js} +14 -10
  47. package/dist/chunks/{studio-vz68yn9e.js → studio-en82c639.js} +6 -6
  48. package/dist/chunks/{studio-rkstz940.js → studio-etvx9s2g.js} +21 -12
  49. package/dist/chunks/{studio-az3zd49t.js → studio-ez11dmdh.js} +127 -37
  50. package/dist/chunks/{studio-sgdc5pfc.js → studio-hdc2jt3z.js} +4 -4
  51. package/dist/chunks/{studio-s6z853aq.js → studio-hhskq2mr.js} +24 -23
  52. package/dist/chunks/{studio-6ewqv390.js → studio-m1p9b6c3.js} +5 -5
  53. package/dist/chunks/{studio-25hkdrkw.js → studio-mpzwze9x.js} +12 -12
  54. package/dist/chunks/{studio-8qtrpzr3.js → studio-ncn9e189.js} +7 -7
  55. package/dist/chunks/{studio-81390n6f.js → studio-nq5yf5mp.js} +1 -1
  56. package/dist/chunks/{studio-5jy81t3s.js → studio-p6pmwkvh.js} +229 -24
  57. package/dist/chunks/{studio-3gxv60tn.js → studio-qa7fzxan.js} +4 -4
  58. package/dist/chunks/{studio-7xptrg0j.js → studio-sar8g54p.js} +8 -8
  59. package/dist/chunks/studio-t171hxhe.js +23 -0
  60. package/dist/chunks/{studio-em9nw8eh.js → studio-t3adrr56.js} +20 -17
  61. package/dist/chunks/{studio-hhvs4sdg.js → studio-vn5hske5.js} +10 -4
  62. package/dist/chunks/{studio-pm6hgy7r.js → studio-vt0tj32j.js} +29 -42
  63. package/dist/chunks/{studio-d1ja2x9r.js → studio-wjpgxywa.js} +4 -4
  64. package/dist/chunks/{studio-q3x06vmj.js → studio-wnsyffg1.js} +2 -2
  65. package/dist/chunks/{studio-rpyah2ew.js → studio-x10fp4tp.js} +64 -24
  66. package/dist/chunks/{studio-26d7myd1.js → studio-x72j58vw.js} +4 -4
  67. package/dist/chunks/{studio-cpvb2ed1.js → studio-y4f9fdge.js} +8 -8
  68. package/dist/chunks/{studio-erdatzvp.js → studio-ympe0n7a.js} +35 -6
  69. package/dist/chunks/{studio-y9zedyjn.js → studio-z2smx5ce.js} +2 -2
  70. package/dist/chunks/studio-zjjde71a.js +148 -0
  71. package/dist/chunks/{workspace-wrew8zk4.js → workspace-bnw54cha.js} +18 -10
  72. package/dist/iframe-entry.js +102 -11
  73. package/dist/studio.css +1 -2
  74. package/dist/studio.js +1113 -16062
  75. package/package.json +11 -11
  76. package/src/canvas/canvas-utils.ts +29 -2
  77. package/src/commands/command-args.ts +37 -2
  78. package/src/commands/registry.ts +18 -8
  79. package/src/commands/run-reported.ts +120 -0
  80. package/src/editor/shortcuts.ts +11 -23
  81. package/src/files/components.ts +39 -0
  82. package/src/files/files.ts +41 -17
  83. package/src/grid/grid-lazy.ts +59 -0
  84. package/src/grid/grid-open.ts +20 -3
  85. package/src/grid/grid-panel.ts +43 -9
  86. package/src/i18n/i18n-commands.ts +10 -0
  87. package/src/media/media-open.ts +14 -2
  88. package/src/packages/pull-package-sync.ts +5 -1
  89. package/src/panels/ai-panel.ts +5 -2
  90. package/src/panels/block-action-bar.ts +7 -2
  91. package/src/panels/i18n-panel.ts +8 -15
  92. package/src/panels/jump-bar.ts +3 -2
  93. package/src/panels/pane-context.ts +5 -4
  94. package/src/panels/pane-grid.ts +100 -10
  95. package/src/panels/problems-panel.ts +6 -2
  96. package/src/panels/quick-search.ts +6 -12
  97. package/src/panels/settings-menu.ts +5 -15
  98. package/src/panels/tab-drop.ts +220 -0
  99. package/src/panels/tab-strip.ts +238 -33
  100. package/src/services/ai-command-tools.ts +78 -8
  101. package/src/services/ai-models.ts +13 -0
  102. package/src/services/ai-project-tools.ts +8 -2
  103. package/src/services/ai-system-prompt.ts +4 -8
  104. package/src/services/ai-tools.ts +8 -69
  105. package/src/services/document-assistant.ts +9 -6
  106. package/src/studio.ts +24 -8
  107. package/src/surfaces/commandbar.json +35 -24
  108. package/src/surfaces/commandbar.ts +6 -5
  109. package/src/surfaces/pane-grid.json +35 -3
  110. package/src/surfaces/pane-grid.ts +26 -4
  111. package/src/surfaces/statusbar.ts +2 -1
  112. package/src/surfaces/tab-strip.json +16 -39
  113. package/src/surfaces/tab-strip.ts +76 -12
  114. package/src/tabs/project-config.ts +45 -11
  115. package/src/ui/ai-credentials-form.ts +12 -1
  116. package/src/ui/layers.ts +4 -1
  117. package/src/workspace/pane-derive.ts +7 -5
  118. package/src/workspace/session.ts +3 -3
  119. package/src/workspace/workspace.ts +220 -43
  120. package/styles/shell-frame.css +8 -0
  121. package/styles/shell-frame.json +4 -0
  122. package/dist/chunks/components-2w1f35qs.js +0 -18
  123. package/dist/chunks/content-source-3wqeas45.js +0 -46
  124. package/dist/chunks/entry-commands-d6g50j7s.js +0 -42
  125. package/dist/chunks/file-ops-3btj6st0.js +0 -47
  126. package/dist/chunks/git-panel-4wp2rn9b.js +0 -49
  127. package/dist/chunks/layers-panel-ar2gh90g.js +0 -40
  128. package/dist/chunks/menu-rf7n72mf.js +0 -14
  129. package/dist/chunks/publish-panel-98f7sr3g.js +0 -27
  130. package/dist/chunks/quick-search-srzz83k2.js +0 -45
  131. package/dist/chunks/right-panel-rrgx2dn3.js +0 -45
  132. package/dist/chunks/studio-d055c37e.js +0 -62
@@ -4,14 +4,14 @@ import {
4
4
  } from "./studio-6nzaktvy.js";
5
5
  import {
6
6
  displayTagName
7
- } from "./studio-7r42c6ca.js";
7
+ } from "./studio-3ntvq6cg.js";
8
8
  import {
9
9
  errorMessage2
10
10
  } from "./studio-yxa81f45.js";
11
11
  import {
12
12
  loadUsages2,
13
13
  usageWarning2
14
- } from "./studio-81390n6f.js";
14
+ } from "./studio-nq5yf5mp.js";
15
15
  import {
16
16
  effectScope,
17
17
  onScopeDispose,
@@ -24,7 +24,7 @@ import {
24
24
  clearProblems2,
25
25
  problemFindings2,
26
26
  problemCount2
27
- } from "./studio-p1dw8wfw.js";
27
+ } from "./studio-d8z5bajd.js";
28
28
  import {
29
29
  loadFormats2,
30
30
  formatByName2,
@@ -34,7 +34,7 @@ import {
34
34
  formatParse2,
35
35
  formatSerialize2,
36
36
  splitFormatDocument2
37
- } from "./studio-79y5sz51.js";
37
+ } from "./studio-28vs5k2y.js";
38
38
  import {
39
39
  getNodeAtPath2,
40
40
  childList,
@@ -42,7 +42,7 @@ import {
42
42
  nodeLabel,
43
43
  projectState,
44
44
  statusbarEl
45
- } from "./studio-6ewqv390.js";
45
+ } from "./studio-m1p9b6c3.js";
46
46
  import {
47
47
  EDITOR_KIND_LABELS,
48
48
  primarySelection,
@@ -59,10 +59,10 @@ import {
59
59
  PRIMARY_PANE2,
60
60
  workspace2,
61
61
  activeTab2
62
- } from "./studio-az3zd49t.js";
62
+ } from "./studio-ez11dmdh.js";
63
63
  import {
64
64
  isMediaFile
65
- } from "./studio-vz68yn9e.js";
65
+ } from "./studio-en82c639.js";
66
66
  import {
67
67
  POPOVER_DEFAULT_MODE,
68
68
  findPopoverDefects,
@@ -70,37 +70,38 @@ import {
70
70
  POPOVER_TAGS,
71
71
  INVOKER_TAGS,
72
72
  activeRegistry
73
- } from "./studio-5jy81t3s.js";
73
+ } from "./studio-p6pmwkvh.js";
74
74
  import {
75
75
  paneRegion,
76
76
  registerSurface,
77
77
  mountSurface,
78
+ runReported,
78
79
  showConfirmDialog2
79
- } from "./studio-erdatzvp.js";
80
+ } from "./studio-ympe0n7a.js";
80
81
  import {
81
82
  openMenu2
82
- } from "./studio-3gxv60tn.js";
83
+ } from "./studio-qa7fzxan.js";
83
84
  import {
84
85
  parseJsonDocument,
85
86
  serializeJson,
86
87
  shell
87
- } from "./studio-25hkdrkw.js";
88
+ } from "./studio-mpzwze9x.js";
88
89
  import {
89
90
  deployStatusItem
90
- } from "./studio-tb3ev01j.js";
91
+ } from "./studio-9j6sfeba.js";
91
92
  import {
92
93
  tabOfPane,
93
94
  derivationOfPane,
94
95
  findDialogDefects,
95
96
  flushCanvasEdits2
96
- } from "./studio-rkstz940.js";
97
+ } from "./studio-etvx9s2g.js";
97
98
  import {
98
99
  isRecentLocal2
99
- } from "./studio-8jn5yhyn.js";
100
+ } from "./studio-4c041r8y.js";
100
101
  import {
101
102
  showProgressModal,
102
103
  loadMediaUsages
103
- } from "./studio-cpvb2ed1.js";
104
+ } from "./studio-y4f9fdge.js";
104
105
  import {
105
106
  validateComponentSlots
106
107
  } from "./studio-q0a3yk4n.js";
@@ -385,7 +386,7 @@ function mountJumpBarSurface(host, region, actions) {
385
386
  var pane_grid_default = {
386
387
  $schema: "https://jxsuite.com/schema/v1",
387
388
  $id: "StudioPaneGrid",
388
- $description: "The pane grid (studio.md §18.1): one cell per pane, with a splitter before every cell but the first. Every box here is EMPTY by design — the four inside a cell are hosts other modules fill (`panels/tab-strip.ts` the strip, `panels/jump-bar.ts` the jump bar, `panels/pane-context.ts` the chrome layer, `canvas/canvas-render.ts` the stage), and the stage is an ISLAND in the §9.4 sense: the canvas host mounts a cross-origin `<iframe>` into it, so nothing this document draws may ever go inside it. What the document owns is the STRUCTURE and the STYLE — the cell's own two-row grid, the three row-2 children that share its lower cell, and the splitter — which is `styles/shell.css`'s `.pane*` block and `styles/canvas.css`'s `.pane-stage` rule, carried here and keyed on `part`. Two things are load-bearing and easy to undo. (1) **A row that moves reloads an iframe**, so the keyed `$map` is not an optimisation: `workspace.panes[0]` is always the primary and `MAX_PANES` is 2, the key is the pane id, and the runtime's forward-cursor pass therefore never moves a kept row — gaining or losing the side pane leaves the primary's node, and the frame inside it, untouched. (2) **The splitter must sit BETWEEN two cells and inside neither**, so each row is a `display: contents` wrapper holding its own leading splitter and its cell: the wrapper generates no box, so the splitter and the two cells are the grid items of `#pane-grid` in DOM order, and a pointer landing on the splitter is in no cell at all. Every selector below is a `>` chain from the root, because a pane's stage hosts other surface documents and a bare `[part=\"row\"]` descendant rule would reach into them.",
389
+ $description: "The pane grid (studio.md §18.1): one cell per pane, with a splitter before every cell but the first. Every box here is EMPTY by design — the FIVE inside a cell are hosts other modules fill (`panels/tab-strip.ts` the strip, `panels/jump-bar.ts` the jump bar, `panels/pane-context.ts` the chrome layer, `canvas/canvas-render.ts` the stage, `panels/pane-grid.ts` itself the right-edge drop zone), and the stage is an ISLAND in the §9.4 sense: the canvas host mounts a cross-origin `<iframe>` into it, so nothing this document draws may ever go inside it. What the document owns is the STRUCTURE and the STYLE — the cell's own two-row grid, the three row-2 children that share its lower cell, and the splitter — which is `styles/shell.css`'s `.pane*` block and `styles/canvas.css`'s `.pane-stage` rule, carried here and keyed on `part`. Two things are load-bearing and easy to undo. (1) **A row that moves reloads an iframe**, so the keyed `$map` is not an optimisation: `workspace.panes[0]` is always the primary and `MAX_PANES` is 2, the key is the pane id, and the runtime's forward-cursor pass therefore never moves a kept row — gaining or losing the side pane leaves the primary's node, and the frame inside it, untouched. (2) **The splitter must sit BETWEEN two cells and inside neither**, so each row is a `display: contents` wrapper holding its own leading splitter and its cell: the wrapper generates no box, so the splitter and the two cells are the grid items of `#pane-grid` in DOM order, and a pointer landing on the splitter is in no cell at all. Every selector below is a `>` chain from the root, because a pane's stage hosts other surface documents and a bare `[part=\"row\"]` descendant rule would reach into them.",
389
390
  tagName: "div",
390
391
  attributes: {
391
392
  part: "grid",
@@ -411,7 +412,7 @@ var pane_grid_default = {
411
412
  zIndex: "10"
412
413
  },
413
414
  '& > [part="row"] > [part="pane"]': {
414
- $description: 'ONE PANE, and one COLUMN, declared. Three children name `grid-row: 2` in order to share the lower cell, and auto-placement answers that by inventing an implicit column each: the jump bar, the chrome layer and the stage lined up side by side, the stage taking a third of the pane and pinning the document to the right edge. `grid-template-columns` is what makes "share the cell" mean it, and every row-2 child restates `grid-column: 1` so a future fourth one cannot re-open the same hole. No unit test can see this — happy-dom does no layout, so every rect is zero — which is why the screenshot lane is what caught it.',
415
+ $description: 'ONE PANE, and one COLUMN, declared. Four children name `grid-row: 2` in order to share the lower cell, and auto-placement answers that by inventing an implicit column each: the jump bar, the chrome layer, the stage and the drop zone lined up side by side, the stage taking a third of the pane and pinning the document to the right edge. `grid-template-columns` is what makes "share the cell" mean it, and every row-2 child restates `grid-column: 1` so a future fifth one cannot re-open the same hole. No unit test can see this — happy-dom does no layout, so every rect is zero — which is why the screenshot lane is what caught it.',
415
416
  display: "grid",
416
417
  gridTemplateColumns: "minmax(0, 1fr)",
417
418
  gridTemplateRows: "auto minmax(0, 1fr)",
@@ -466,11 +467,33 @@ var pane_grid_default = {
466
467
  display: "flex",
467
468
  gap: "var(--jx-space-6)",
468
469
  alignItems: "flex-start"
470
+ },
471
+ '& > [part="row"] > [part="pane"] > [part="drop-zone"]': {
472
+ $description: "The right-edge target that creates a second pane (§18.1). Sits ABOVE the stage (`z-index: 4` against the stage's own stacking, jump's 3, chrome's 2) so a drag reaches it before it reaches the cross-origin iframe underneath, which would otherwise swallow every drag event with no affordance to say so. `pointer-events: none` when unarmed — a mouse doing anything other than dragging a tab or a file must pass straight through to the stage — and `auto` only while `data-armed` is set, which `panels/pane-grid.ts`'s own arming monitor writes for the DURATION of a drag it recognises, never for a click.",
473
+ gridRow: "2",
474
+ gridColumn: "1",
475
+ position: "relative",
476
+ zIndex: "4",
477
+ minWidth: "0",
478
+ pointerEvents: "none"
479
+ },
480
+ '& > [part="row"] > [part="pane"] > [part="drop-zone"][data-armed]': {
481
+ pointerEvents: "auto"
482
+ },
483
+ '& > [part="row"] > [part="pane"] > [part="drop-zone"][data-over]::after': {
484
+ $description: "The right BAND, not the whole cell: the zone only ever ACCEPTS a drop in that band (`panels/pane-grid.ts`'s `edgeData`), so lighting the whole cell would promise a drop this element refuses everywhere else in it.",
485
+ content: '""',
486
+ position: "absolute",
487
+ insetBlock: "0",
488
+ insetInlineEnd: "0",
489
+ insetInlineStart: "50%",
490
+ background: "color-mix(in srgb, var(--accent) 14%, transparent)",
491
+ borderInlineStart: "2px solid var(--accent)"
469
492
  }
470
493
  },
471
494
  children: [
472
495
  {
473
- $description: "Keyed on the PANE ID, and that is the whole of §18.1 rule 1's structural half: the key is what makes the runtime MOVE a kept row rather than rebuild it, and re-parenting is not a move for an `<iframe>` — it reloads, dropping its `iframe-channel` connection, its shadow document and every `ready` panel with it. A row renders complete (its cell, its four hosts and its splitter) inside the row's own effect scope before it is inserted, so there is no frame in which a cell exists with no stage inside it.",
496
+ $description: "Keyed on the PANE ID, and that is the whole of §18.1 rule 1's structural half: the key is what makes the runtime MOVE a kept row rather than rebuild it, and re-parenting is not a move for an `<iframe>` — it reloads, dropping its `iframe-channel` connection, its shadow document and every `ready` panel with it. A row renders complete (its cell, its five hosts and its splitter) inside the row's own effect scope before it is inserted, so there is no frame in which a cell exists with no stage inside it.",
474
497
  $prototype: "Array",
475
498
  items: { $ref: "#/state/rows" },
476
499
  key: { $ref: "$map/item/id" },
@@ -562,6 +585,16 @@ var pane_grid_default = {
562
585
  part: "pane-stage",
563
586
  "data-jx-region": "${$map.item.region}"
564
587
  }
588
+ },
589
+ {
590
+ $description: "The right-edge drop target (§18.1). No `data-jx-region`: `pane.<id>` uniqueness names the stage, and a second element answering to it would be a silently widened crop the moment a shot cropped this pane.",
591
+ tagName: "div",
592
+ attributes: {
593
+ part: "drop-zone",
594
+ role: "none",
595
+ "data-armed": "${state.armed ? '' : null}",
596
+ "data-over": "${state.edgePane === $map.item.id ? '' : null}"
597
+ }
565
598
  }
566
599
  ]
567
600
  }
@@ -582,7 +615,8 @@ var CELL_PARTS = new Map([
582
615
  ["strip", "strip"],
583
616
  ["jump", "jump"],
584
617
  ["chrome", "chrome"],
585
- ["pane-stage", "stage"]
618
+ ["pane-stage", "stage"],
619
+ ["drop-zone", "dropZone"]
586
620
  ]);
587
621
  function partOf(def) {
588
622
  const part = typeof def === "string" ? undefined : def.attributes?.["part"];
@@ -595,6 +629,8 @@ function paneOf(state) {
595
629
  function mountPaneGridSurface(host, rows, split, actions) {
596
630
  host.replaceChildren();
597
631
  const scope = reactive({
632
+ armed: false,
633
+ edgePane: "",
598
634
  move: actions.move,
599
635
  paneSplit: split.value,
600
636
  rows,
@@ -627,6 +663,10 @@ function mountPaneGridSurface(host, rows, split, actions) {
627
663
  mounted = null;
628
664
  host.replaceChildren();
629
665
  },
666
+ drag(state) {
667
+ scope.armed = state.armed;
668
+ scope.edgePane = state.edgePane;
669
+ },
630
670
  ready,
631
671
  update(next, value) {
632
672
  scope.rows = next;
@@ -805,7 +845,7 @@ function openChoices(segment, anchor) {
805
845
  dividerAbove: false,
806
846
  id: String(i),
807
847
  run: () => {
808
- registry.run(choice.command, choice.args);
848
+ runReported(registry, choice.command, choice.args, "Jump Bar");
809
849
  },
810
850
  title: choice.label
811
851
  }));
@@ -876,7 +916,7 @@ function attachJumpBarHost(paneId, host) {
876
916
  const segment = _bars.get(paneId)?.segments.get(key);
877
917
  const registry = activeRegistry();
878
918
  if (segment?.command && registry) {
879
- registry.run(segment.command, segment.args);
919
+ runReported(registry, segment.command, segment.args, "Jump Bar");
880
920
  }
881
921
  }
882
922
  })
@@ -1196,7 +1236,7 @@ function state() {
1196
1236
  const item = _state?.fields.flatMap((field) => field.items).find((i) => i.key === key);
1197
1237
  const registry = activeRegistry();
1198
1238
  if (item?.command && registry) {
1199
- registry.run(item.command, item.args);
1239
+ runReported(registry, item.command, item.args, "Status Bar");
1200
1240
  }
1201
1241
  }
1202
1242
  });
@@ -2801,5 +2841,5 @@ async function renamePromptMessage2(path, verb = "rename") {
2801
2841
 
2802
2842
  export { cellValuesEqual, makeGridTabId, parseGridTabId, gridTabLabel, columnsFromSchema, inferColumnsFromRows, coerceCellInput, cellToText, ROW_KEY_FIELD, getGridController, createGridController, PANE_SELECTOR, STAGE_SELECTOR, mountPaneGridSurface, attachJumpBarHost, mountJumpBar, projectSessions, renderStatusbar, mountStatusbar, registerPopoverCommands, serializeDocument, notePreviewOverlayEdit, armPreviewOverlay, disarmPreviewOverlay, flushPreviewOverlay, mediaTypeEssence, parseSourceForPath2, parseCollabSource2, setDocumentSavedListener2, saveFile2, exportFile2, confirmFileDelete2, renamePromptMessage2 };
2803
2843
 
2804
- //# debugId=F690D395FACA498E64756E2164756E21
2805
- //# sourceMappingURL=studio-rpyah2ew.js.map
2844
+ //# debugId=DBDB9C97E212B0A564756E2164756E21
2845
+ //# sourceMappingURL=studio-x10fp4tp.js.map
@@ -2,13 +2,13 @@ import {
2
2
  resolveI18n,
3
3
  emptyContext,
4
4
  activeTab2
5
- } from "./studio-az3zd49t.js";
5
+ } from "./studio-ez11dmdh.js";
6
6
  import {
7
7
  projectState
8
- } from "./studio-6ewqv390.js";
8
+ } from "./studio-m1p9b6c3.js";
9
9
  import {
10
10
  shell
11
- } from "./studio-25hkdrkw.js";
11
+ } from "./studio-mpzwze9x.js";
12
12
 
13
13
  // src/commands/levels.ts
14
14
  var LEVELS = ["application", "project", "document", "selection"];
@@ -255,4 +255,4 @@ function railPanelSet() {
255
255
  export { LEVELS, KEY_SCOPES, CATEGORIES, checkRecordPlacements, panelContext, registerPanel, getPanel, listPanels, isPanelVisible, railGroups, railPanelSet };
256
256
 
257
257
  //# debugId=18BC2C98470D23FD64756E2164756E21
258
- //# sourceMappingURL=studio-26d7myd1.js.map
258
+ //# sourceMappingURL=studio-x72j58vw.js.map
@@ -5,20 +5,20 @@ import {
5
5
  normalizeProjectPath,
6
6
  showModal,
7
7
  close2
8
- } from "./studio-5jy81t3s.js";
8
+ } from "./studio-p6pmwkvh.js";
9
9
  import {
10
10
  syncDeployChecklist
11
- } from "./studio-tb3ev01j.js";
11
+ } from "./studio-9j6sfeba.js";
12
12
  import {
13
13
  effectScope,
14
14
  effect,
15
15
  reactive,
16
16
  now,
17
17
  notify2
18
- } from "./studio-p1dw8wfw.js";
18
+ } from "./studio-d8z5bajd.js";
19
19
  import {
20
20
  setBottomTab
21
- } from "./studio-25hkdrkw.js";
21
+ } from "./studio-mpzwze9x.js";
22
22
  import {
23
23
  REGION_ATTR,
24
24
  overlayRegion,
@@ -26,15 +26,15 @@ import {
26
26
  mountSurface,
27
27
  whenReady,
28
28
  layerHost2
29
- } from "./studio-erdatzvp.js";
29
+ } from "./studio-ympe0n7a.js";
30
30
  import {
31
31
  registerPanel
32
- } from "./studio-26d7myd1.js";
32
+ } from "./studio-x72j58vw.js";
33
33
  import {
34
34
  peekUsages2,
35
35
  loadUsages2,
36
36
  usageHeadline2
37
- } from "./studio-81390n6f.js";
37
+ } from "./studio-nq5yf5mp.js";
38
38
  // src/surfaces/panel-activity.json
39
39
  var panel_activity_default = {
40
40
  $schema: "https://jxsuite.com/schema/v1",
@@ -1168,4 +1168,4 @@ function showProgressModal(opts) {
1168
1168
  export { beginActivity, activityIdleBlockers, registerActivityPanel, showProgressModal, peekMediaUsages, loadMediaUsages, mediaUsageHeadline };
1169
1169
 
1170
1170
  //# debugId=0FE9D80FF9C2142764756E2164756E21
1171
- //# sourceMappingURL=studio-cpvb2ed1.js.map
1171
+ //# sourceMappingURL=studio-y4f9fdge.js.map
@@ -10,14 +10,18 @@ import {
10
10
  selectValue,
11
11
  registerUi,
12
12
  activeRegistry
13
- } from "./studio-5jy81t3s.js";
13
+ } from "./studio-p6pmwkvh.js";
14
14
  import {
15
15
  effectScope,
16
16
  effect,
17
17
  reactive,
18
18
  toasts2,
19
+ notify2,
19
20
  dismiss2
20
- } from "./studio-p1dw8wfw.js";
21
+ } from "./studio-d8z5bajd.js";
22
+ import {
23
+ errorMessage2
24
+ } from "./studio-yxa81f45.js";
21
25
 
22
26
  // src/ui/regions.ts
23
27
  var REGION_ATTR = "data-jx-region";
@@ -875,6 +879,31 @@ var toasts_default = {
875
879
  ]
876
880
  };
877
881
 
882
+ // src/commands/run-reported.ts
883
+ function isRefusal(error) {
884
+ return error instanceof RangeError || error instanceof Error && error.name === "CommandUnavailableError";
885
+ }
886
+ function runReported(registry, id, args, source = id) {
887
+ const report = (error) => {
888
+ if (!isRefusal(error)) {
889
+ console.error(`${source}: command "${id}" failed`, error);
890
+ }
891
+ notify2.error(errorMessage2(error), { key: `command.run:${id}`, source });
892
+ };
893
+ let result;
894
+ try {
895
+ result = registry.run(id, args);
896
+ } catch (error) {
897
+ report(error);
898
+ return Promise.resolve();
899
+ }
900
+ return Promise.resolve(result).catch(report);
901
+ }
902
+ function runActiveReported(id, args, source) {
903
+ const registry = activeRegistry();
904
+ return registry ? runReported(registry, id, args, source) : Promise.resolve();
905
+ }
906
+
878
907
  // src/ui/layers.ts
879
908
  var _popoverLayer;
880
909
  var _modalLayer;
@@ -1121,7 +1150,7 @@ function toastScope() {
1121
1150
  return;
1122
1151
  }
1123
1152
  retireToast(id);
1124
- registry.run(record.action, record.actionArgs);
1153
+ runReported(registry, record.action, record.actionArgs, "Notifications");
1125
1154
  },
1126
1155
  toasts: []
1127
1156
  });
@@ -1184,7 +1213,7 @@ function unmountToastHost() {
1184
1213
  _toastState = null;
1185
1214
  }
1186
1215
 
1187
- export { mountsUsing, mountsOf, registerKit, REGION_ATTR, resolveRegion, REGION_FOR_FOCUS, paneRegion, paneStripRegion, navigatorPanelRegion, inspectorTabRegion, NAVIGATOR_STATEMENTS_REGION, inspectorStatementsRegion, bottomPanelRegion, overlayRegion, registerSurface, surfaceDocument, mountSurface, whenReady, openDialogSurface, layerHost2, initLayers2, isModalOpen2, showConfirmDialog2, showSaveDiscardDialog2, showPromptDialog2, getLayerSlot2, clearLayerSlot2, overlayIdleBlockers2 };
1216
+ export { mountsUsing, mountsOf, registerKit, REGION_ATTR, resolveRegion, REGION_FOR_FOCUS, paneRegion, paneStripRegion, navigatorPanelRegion, inspectorTabRegion, NAVIGATOR_STATEMENTS_REGION, inspectorStatementsRegion, bottomPanelRegion, overlayRegion, registerSurface, surfaceDocument, mountSurface, whenReady, openDialogSurface, runReported, runActiveReported, layerHost2, initLayers2, isModalOpen2, showConfirmDialog2, showSaveDiscardDialog2, showPromptDialog2, getLayerSlot2, clearLayerSlot2, overlayIdleBlockers2 };
1188
1217
 
1189
- //# debugId=A8CBC6598506FDAE64756E2164756E21
1190
- //# sourceMappingURL=studio-erdatzvp.js.map
1218
+ //# debugId=0892C6B4A7BF4FE464756E2164756E21
1219
+ //# sourceMappingURL=studio-ympe0n7a.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./studio-6nzaktvy.js";
5
5
  import {
6
6
  notify2
7
- } from "./studio-p1dw8wfw.js";
7
+ } from "./studio-d8z5bajd.js";
8
8
 
9
9
  // src/services/settings/definitions.ts
10
10
  function normalizeBaseUrl(raw) {
@@ -279,4 +279,4 @@ function watchRemoteSettings() {
279
279
  export { SETTINGS, readStoredSetting, hasSetting, onSettingsChanged, settingsSettled, setSetting, setSettings, clearSettings, hydrateSettings, watchRemoteSettings };
280
280
 
281
281
  //# debugId=8DE88702AC5D888464756E2164756E21
282
- //# sourceMappingURL=studio-y9zedyjn.js.map
282
+ //# sourceMappingURL=studio-z2smx5ce.js.map
@@ -0,0 +1,148 @@
1
+ import {
2
+ getPlatform2
3
+ } from "./studio-6nzaktvy.js";
4
+ import {
5
+ projectState
6
+ } from "./studio-m1p9b6c3.js";
7
+
8
+ // ../schema/src/component-meta.ts
9
+ function collectSlotDefs(node, out = []) {
10
+ if (!node || typeof node !== "object" || Array.isArray(node)) {
11
+ return out;
12
+ }
13
+ const el = node;
14
+ if (el.tagName === "slot") {
15
+ const attrs = el.attributes;
16
+ const rawName = attrs?.name;
17
+ const name = typeof rawName === "string" ? rawName.trim() : "";
18
+ const { children } = el;
19
+ out.push({
20
+ name,
21
+ ...Array.isArray(children) && children.length > 0 ? { fallback: children } : {}
22
+ });
23
+ }
24
+ if (Array.isArray(el.children)) {
25
+ for (const c of el.children) {
26
+ collectSlotDefs(c, out);
27
+ }
28
+ }
29
+ return out;
30
+ }
31
+ function isPropEntry(def) {
32
+ if (def == null) {
33
+ return false;
34
+ }
35
+ if (typeof def !== "object") {
36
+ return true;
37
+ }
38
+ const obj = def;
39
+ return !obj.$prototype && !obj.$handler && !obj.$compute;
40
+ }
41
+ function componentMetaFrom(doc, path) {
42
+ if (!doc || typeof doc !== "object" || Array.isArray(doc)) {
43
+ return null;
44
+ }
45
+ const content = doc;
46
+ const { tagName } = content;
47
+ if (typeof tagName !== "string" || !tagName.includes("-")) {
48
+ return null;
49
+ }
50
+ const slots = collectSlotDefs(content);
51
+ const state = content.state ?? {};
52
+ return {
53
+ $id: typeof content.$id === "string" && content.$id ? content.$id : null,
54
+ hasElements: Array.isArray(content.$elements) && content.$elements.length > 0,
55
+ path,
56
+ props: Object.entries(state).filter(([, def]) => isPropEntry(def)).map(([name, def]) => {
57
+ if (typeof def !== "object" || def === null) {
58
+ return { default: def, name, type: typeof def };
59
+ }
60
+ const obj = def;
61
+ return {
62
+ default: obj.default,
63
+ format: obj.format,
64
+ name,
65
+ type: obj.type
66
+ };
67
+ }),
68
+ ...slots.length > 0 ? { slots } : {},
69
+ tagName
70
+ };
71
+ }
72
+
73
+ // src/files/components.ts
74
+ var componentRegistry2 = [];
75
+ var _componentRegistryLoaded = false;
76
+ async function loadComponentRegistry2() {
77
+ try {
78
+ const platform = getPlatform2();
79
+ componentRegistry2 = await platform.discoverComponents(projectState?.projectRoot || undefined);
80
+ _componentRegistryLoaded = true;
81
+ } catch {
82
+ _componentRegistryLoaded = true;
83
+ }
84
+ }
85
+ function noteComponentSaved2(path, doc) {
86
+ if (!path) {
87
+ return false;
88
+ }
89
+ const index = componentRegistry2.findIndex((c) => c.path === path);
90
+ const meta = componentMetaFrom(doc, path);
91
+ if (!meta) {
92
+ if (index === -1) {
93
+ return false;
94
+ }
95
+ componentRegistry2.splice(index, 1);
96
+ return true;
97
+ }
98
+ const entry = meta;
99
+ if (index === -1) {
100
+ componentRegistry2.push(entry);
101
+ } else {
102
+ componentRegistry2[index] = entry;
103
+ }
104
+ return true;
105
+ }
106
+ function buildComponentInstance2(comp) {
107
+ const $props = Object.fromEntries((comp.props ?? []).map((p) => [p.name, p.default !== undefined ? p.default : ""]));
108
+ const children = [];
109
+ for (const slot of comp.slots ?? []) {
110
+ for (const child of structuredClone(slot.fallback ?? [])) {
111
+ if (!slot.name) {
112
+ children.push(child);
113
+ } else if (typeof child === "object" && child !== null && typeof child.tagName === "string") {
114
+ child.attributes = { slot: slot.name, ...child.attributes };
115
+ children.push(child);
116
+ } else {
117
+ children.push({ attributes: { slot: slot.name }, children: [child], tagName: "span" });
118
+ }
119
+ }
120
+ }
121
+ return {
122
+ $props,
123
+ tagName: comp.tagName,
124
+ ...children.length > 0 ? { children } : {}
125
+ };
126
+ }
127
+ function computeRelativePath2(fromDocPath, toCompPath) {
128
+ if (!fromDocPath) {
129
+ return `./${toCompPath}`;
130
+ }
131
+ const from = fromDocPath.replaceAll("\\", "/");
132
+ const to = toCompPath.replaceAll("\\", "/");
133
+ const fromDir = from.includes("/") ? from.slice(0, from.lastIndexOf("/")) : "";
134
+ const fromParts = fromDir.split("/").filter(Boolean);
135
+ const toParts = to.split("/").filter(Boolean);
136
+ let common = 0;
137
+ while (common < fromParts.length && common < toParts.length && fromParts[common] === toParts[common]) {
138
+ common += 1;
139
+ }
140
+ const ups = fromParts.length - common;
141
+ const remaining = toParts.slice(common);
142
+ return (ups > 0 ? "../".repeat(ups) : "./") + remaining.join("/");
143
+ }
144
+
145
+ export { componentMetaFrom, componentRegistry2, loadComponentRegistry2, noteComponentSaved2, buildComponentInstance2, computeRelativePath2 };
146
+
147
+ //# debugId=466165F8ABAECB0564756E2164756E21
148
+ //# sourceMappingURL=studio-zjjde71a.js.map
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  PRIMARY_PANE2,
3
3
  SECONDARY_PANE2,
4
+ MAX_PANES2,
4
5
  workspace2,
5
6
  activeTab2,
6
7
  activePane2,
@@ -8,8 +9,11 @@ import {
8
9
  paneOfTab2,
9
10
  focusPane2,
10
11
  isPaneFocused2,
11
- sidePane2,
12
+ splitRight2,
13
+ paneBeside2,
12
14
  receivingPane2,
15
+ closePane2,
16
+ paneIsEmpty2,
13
17
  detachTab2,
14
18
  insertIntoPane2,
15
19
  setWorkspaceProject2,
@@ -27,20 +31,22 @@ import {
27
31
  moveTabToPane2,
28
32
  renameTab2,
29
33
  registerTabCommands2
30
- } from "./studio-az3zd49t.js";
31
- import"./studio-q3x06vmj.js";
32
- import"./studio-6ewqv390.js";
33
- import"./studio-79y5sz51.js";
34
+ } from "./studio-ez11dmdh.js";
35
+ import"./studio-wnsyffg1.js";
36
+ import"./studio-m1p9b6c3.js";
37
+ import"./studio-28vs5k2y.js";
34
38
  import"./studio-6nzaktvy.js";
35
- import"./studio-p1dw8wfw.js";
36
- import"./studio-7r42c6ca.js";
39
+ import"./studio-3ntvq6cg.js";
40
+ import"./studio-d8z5bajd.js";
37
41
  export {
42
+ MAX_PANES2 as MAX_PANES,
38
43
  PRIMARY_PANE2 as PRIMARY_PANE,
39
44
  SECONDARY_PANE2 as SECONDARY_PANE,
40
45
  activateTab2 as activateTab,
41
46
  activePane2 as activePane,
42
47
  activeTab2 as activeTab,
43
48
  closeAllTabs2 as closeAllTabs,
49
+ closePane2 as closePane,
44
50
  closeTab2 as closeTab,
45
51
  detachTab2 as detachTab,
46
52
  focusPane2 as focusPane,
@@ -50,7 +56,9 @@ export {
50
56
  moveTab2 as moveTab,
51
57
  moveTabToPane2 as moveTabToPane,
52
58
  openTab2 as openTab,
59
+ paneBeside2 as paneBeside,
53
60
  paneById2 as paneById,
61
+ paneIsEmpty2 as paneIsEmpty,
54
62
  paneOfTab2 as paneOfTab,
55
63
  promoteDirtyPreviewTabs2 as promoteDirtyPreviewTabs,
56
64
  promoteTab2 as promoteTab,
@@ -60,10 +68,10 @@ export {
60
68
  replaceAllTabs2 as replaceAllTabs,
61
69
  setTabPinned2 as setTabPinned,
62
70
  setWorkspaceProject2 as setWorkspaceProject,
63
- sidePane2 as sidePane,
71
+ splitRight2 as splitRight,
64
72
  tabIsLive2 as tabIsLive,
65
73
  workspace2 as workspace
66
74
  };
67
75
 
68
- //# debugId=38ABE52702AF922364756E2164756E21
69
- //# sourceMappingURL=workspace-wrew8zk4.js.map
76
+ //# debugId=DAA0C7B0A6B56CB064756E2164756E21
77
+ //# sourceMappingURL=workspace-bnw54cha.js.map