@tutti-os/workbench-surface 0.0.75 → 0.0.76

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.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  workbenchHostI18nResources,
6
6
  workbenchWindowChromeI18nNamespace,
7
7
  workbenchWindowChromeI18nResources
8
- } from "./chunk-B5MSA47V.js";
8
+ } from "./chunk-TIMYSQM7.js";
9
9
 
10
10
  // src/store/commands.ts
11
11
  function createWorkbenchCommands(store) {
@@ -40,12 +40,21 @@ function createWorkbenchCommands(store) {
40
40
  applyQuickLayout(nodeID, target) {
41
41
  store.dispatch({ type: "applyQuickLayout", nodeID, target });
42
42
  },
43
- applyLayoutPreset(nodeIDs, preset) {
44
- store.dispatch({ type: "applyLayoutPreset", nodeIDs, preset });
43
+ applyLayoutPreset(nodeIDs, preset, lock) {
44
+ store.dispatch({ type: "applyLayoutPreset", nodeIDs, preset, lock });
45
45
  },
46
46
  applyVisibleLayoutPreset(preset) {
47
47
  store.dispatch({ type: "applyVisibleLayoutPreset", preset });
48
48
  },
49
+ settleLockedDrag(nodeID) {
50
+ store.dispatch({ type: "settleLockedDrag", nodeID });
51
+ },
52
+ moveLockedNode(nodeID, direction) {
53
+ store.dispatch({ type: "moveLockedNode", nodeID, direction });
54
+ },
55
+ releaseLockedLayout() {
56
+ store.dispatch({ type: "releaseLockedLayout" });
57
+ },
49
58
  applyActiveSnapTarget(nodeID) {
50
59
  store.dispatch({ type: "applyActiveSnapTarget", nodeID });
51
60
  },
@@ -400,6 +409,57 @@ function getWorkbenchLayoutPresetFrames(itemCount, preset, surfaceSize, constrai
400
409
  return getSingleColumnLayoutFrames(itemCount, frame, normalized);
401
410
  }
402
411
  }
412
+ function normalizeWorkbenchFrameToRect(frame, rect) {
413
+ const width = Math.max(rect.width, 1);
414
+ const height = Math.max(rect.height, 1);
415
+ return {
416
+ x: (frame.x - rect.x) / width,
417
+ y: (frame.y - rect.y) / height,
418
+ width: frame.width / width,
419
+ height: frame.height / height
420
+ };
421
+ }
422
+ function denormalizeWorkbenchFrameFromRect(normalized, rect) {
423
+ return {
424
+ x: rect.x + normalized.x * rect.width,
425
+ y: rect.y + normalized.y * rect.height,
426
+ width: normalized.width * rect.width,
427
+ height: normalized.height * rect.height
428
+ };
429
+ }
430
+ function getWorkbenchLockedSlotFrames(lockedLayout, surfaceSize, constraints = defaultWorkbenchLayoutConstraints) {
431
+ if (!lockedLayout || lockedLayout.nodeIDs.length < 2) {
432
+ return null;
433
+ }
434
+ const normalizedFrames = lockedLayout.normalizedFrames;
435
+ if (normalizedFrames) {
436
+ const rect = getWorkbenchSafeLayoutRect(surfaceSize, constraints);
437
+ const slots = [];
438
+ for (const nodeID of lockedLayout.nodeIDs) {
439
+ const normalized = normalizedFrames[nodeID];
440
+ if (normalized) {
441
+ slots.push({
442
+ nodeID,
443
+ frame: denormalizeWorkbenchFrameFromRect(normalized, rect)
444
+ });
445
+ }
446
+ }
447
+ return slots.length >= 2 ? slots : null;
448
+ }
449
+ const frames = getWorkbenchLayoutPresetFrames(
450
+ lockedLayout.nodeIDs.length,
451
+ lockedLayout.preset,
452
+ surfaceSize,
453
+ constraints
454
+ );
455
+ if (!frames) {
456
+ return null;
457
+ }
458
+ return lockedLayout.nodeIDs.map((nodeID, index) => ({
459
+ nodeID,
460
+ frame: frames[index]
461
+ }));
462
+ }
403
463
  function getWorkbenchSafeLayoutRect(surfaceSize, constraints = defaultWorkbenchLayoutConstraints) {
404
464
  const normalized = normalizeWorkbenchLayoutConstraints(constraints);
405
465
  const frame = getWorkbenchLayoutFrame(surfaceSize, normalized);
@@ -595,7 +655,8 @@ function createWorkbenchInitialState(partial = {}) {
595
655
  surfaceSize: partial.surfaceSize ?? defaultWorkbenchSurfaceSize,
596
656
  layoutConstraints: normalizeWorkbenchLayoutConstraints(
597
657
  partial.layoutConstraints ?? defaultWorkbenchLayoutConstraints
598
- )
658
+ ),
659
+ lockedLayout: partial.lockedLayout ?? null
599
660
  };
600
661
  }
601
662
  function reduceWorkbenchState(state, action) {
@@ -605,7 +666,7 @@ function reduceWorkbenchState(state, action) {
605
666
  ...state,
606
667
  ...action.state
607
668
  });
608
- if (state.nodes === nextState.nodes && state.nodeStack === nextState.nodeStack && state.activeDragNodeId === nextState.activeDragNodeId && state.activeResizeNodeId === nextState.activeResizeNodeId && state.activeSnapTarget === nextState.activeSnapTarget && state.surfaceSize === nextState.surfaceSize && layoutConstraintsEqual(
669
+ if (state.nodes === nextState.nodes && state.nodeStack === nextState.nodeStack && state.activeDragNodeId === nextState.activeDragNodeId && state.activeResizeNodeId === nextState.activeResizeNodeId && state.activeSnapTarget === nextState.activeSnapTarget && state.surfaceSize === nextState.surfaceSize && state.lockedLayout === nextState.lockedLayout && layoutConstraintsEqual(
609
670
  state.layoutConstraints,
610
671
  nextState.layoutConstraints
611
672
  )) {
@@ -625,7 +686,7 @@ function reduceWorkbenchState(state, action) {
625
686
  const nodes = existing ? state.nodes.map(
626
687
  (node) => node.id === action.node.id ? action.node : node
627
688
  ) : [...state.nodes, action.node];
628
- return {
689
+ const openedState = {
629
690
  ...state,
630
691
  nodes,
631
692
  nodeStack: focusWorkbenchStack(
@@ -633,6 +694,18 @@ function reduceWorkbenchState(state, action) {
633
694
  action.node.id
634
695
  )
635
696
  };
697
+ if (!existing && state.lockedLayout) {
698
+ const grownState = applyLayoutPresetToNodes(
699
+ openedState,
700
+ [...state.lockedLayout.nodeIDs, action.node.id],
701
+ state.lockedLayout.preset,
702
+ { lock: true, reorderStack: false }
703
+ );
704
+ if (grownState !== openedState) {
705
+ return grownState;
706
+ }
707
+ }
708
+ return openedState;
636
709
  }
637
710
  case "closeNode":
638
711
  if (!state.nodes.some((node) => node.id === action.nodeID)) {
@@ -641,7 +714,8 @@ function reduceWorkbenchState(state, action) {
641
714
  return {
642
715
  ...state,
643
716
  nodes: state.nodes.filter((node) => node.id !== action.nodeID),
644
- nodeStack: removeFromWorkbenchStack(state.nodeStack, action.nodeID)
717
+ nodeStack: removeFromWorkbenchStack(state.nodeStack, action.nodeID),
718
+ lockedLayout: pruneLockedLayout(state.lockedLayout, action.nodeID)
645
719
  };
646
720
  case "focusNode":
647
721
  if (!state.nodes.some((node) => node.id === action.nodeID)) {
@@ -721,13 +795,25 @@ function reduceWorkbenchState(state, action) {
721
795
  };
722
796
  });
723
797
  case "applyLayoutPreset":
724
- return applyLayoutPresetToNodes(state, action.nodeIDs, action.preset);
798
+ return applyLayoutPresetToNodes(state, action.nodeIDs, action.preset, {
799
+ lock: action.lock ?? false
800
+ });
725
801
  case "applyVisibleLayoutPreset":
726
802
  return applyLayoutPresetToNodes(
727
803
  state,
728
804
  state.nodes.filter((node) => !node.isMinimized).map((node) => node.id),
729
- action.preset
805
+ action.preset,
806
+ { lock: false }
730
807
  );
808
+ case "settleLockedDrag":
809
+ return settleLockedDrag(state, action.nodeID);
810
+ case "moveLockedNode":
811
+ return moveLockedNode(state, action.nodeID, action.direction);
812
+ case "releaseLockedLayout":
813
+ if (state.lockedLayout === null) {
814
+ return state;
815
+ }
816
+ return { ...state, lockedLayout: null };
731
817
  case "applyActiveSnapTarget":
732
818
  case "applySnapTarget":
733
819
  return updateNode(state, action.nodeID, (node) => {
@@ -752,8 +838,8 @@ function reduceWorkbenchState(state, action) {
752
838
  minimizedAtUnixMs: null
753
839
  };
754
840
  });
755
- case "dragNode":
756
- return updateNode(state, action.nodeID, (node) => {
841
+ case "dragNode": {
842
+ const draggedState = updateNode(state, action.nodeID, (node) => {
757
843
  const frame = clampWorkbenchDragRect(
758
844
  action.frame,
759
845
  state.surfaceSize,
@@ -770,25 +856,37 @@ function reduceWorkbenchState(state, action) {
770
856
  restoreFrame: node.displayMode === "fullscreen" ? node.restoreFrame : null
771
857
  };
772
858
  });
859
+ if (isLockedLayoutNode(state, action.nodeID)) {
860
+ return draggedState;
861
+ }
862
+ return releaseLockedLayout(state, draggedState);
863
+ }
773
864
  case "moveNode":
774
- case "resizeNode":
775
- return updateNode(state, action.nodeID, (node) => {
776
- const frame = clampWorkbenchRect(
777
- action.frame,
778
- state.surfaceSize,
779
- state.layoutConstraints,
780
- node.sizeConstraints
781
- );
782
- if (rectsEqual(node.frame, frame)) {
783
- return node;
784
- }
785
- return {
786
- ...node,
787
- frame,
788
- displayMode: "floating",
789
- restoreFrame: node.displayMode === "fullscreen" ? node.restoreFrame : null
790
- };
791
- });
865
+ case "resizeNode": {
866
+ if (action.type === "resizeNode" && isLockedLayoutNode(state, action.nodeID)) {
867
+ return resizeLockedGrid(state, action.nodeID, action.frame);
868
+ }
869
+ return releaseLockedLayout(
870
+ state,
871
+ updateNode(state, action.nodeID, (node) => {
872
+ const frame = clampWorkbenchRect(
873
+ action.frame,
874
+ state.surfaceSize,
875
+ state.layoutConstraints,
876
+ node.sizeConstraints
877
+ );
878
+ if (rectsEqual(node.frame, frame)) {
879
+ return node;
880
+ }
881
+ return {
882
+ ...node,
883
+ frame,
884
+ displayMode: "floating",
885
+ restoreFrame: node.displayMode === "fullscreen" ? node.restoreFrame : null
886
+ };
887
+ })
888
+ );
889
+ }
792
890
  case "setActiveDragNode":
793
891
  if (state.activeDragNodeId === action.nodeID) {
794
892
  return state;
@@ -804,11 +902,11 @@ function reduceWorkbenchState(state, action) {
804
902
  return state;
805
903
  }
806
904
  return { ...state, activeSnapTarget: action.snapTarget };
807
- case "setSurfaceSize":
905
+ case "setSurfaceSize": {
808
906
  if (state.surfaceSize.width === action.size.width && state.surfaceSize.height === action.size.height) {
809
907
  return state;
810
908
  }
811
- return {
909
+ const resizedState = {
812
910
  ...state,
813
911
  surfaceSize: action.size,
814
912
  nodes: state.nodes.map(
@@ -831,6 +929,19 @@ function reduceWorkbenchState(state, action) {
831
929
  }
832
930
  )
833
931
  };
932
+ if (state.lockedLayout && state.lockedLayout.nodeIDs.length >= 2) {
933
+ if (state.lockedLayout.normalizedFrames) {
934
+ return materializeLockedFrames(resizedState, state.lockedLayout);
935
+ }
936
+ return applyLayoutPresetToNodes(
937
+ resizedState,
938
+ state.lockedLayout.nodeIDs,
939
+ state.lockedLayout.preset,
940
+ { lock: true, reorderStack: false }
941
+ );
942
+ }
943
+ return resizedState;
944
+ }
834
945
  case "setLayoutConstraints": {
835
946
  const constraints = normalizeWorkbenchLayoutConstraints({
836
947
  ...state.layoutConstraints,
@@ -931,7 +1042,7 @@ function updateNode(state, nodeID, update) {
931
1042
  nodeStack: focusWorkbenchStack(state.nodeStack, nodeID)
932
1043
  };
933
1044
  }
934
- function applyLayoutPresetToNodes(state, inputNodeIDs, preset) {
1045
+ function applyLayoutPresetToNodes(state, inputNodeIDs, preset, options) {
935
1046
  const nodeIDs = uniqueKnownNodeIDs(state.nodes, inputNodeIDs);
936
1047
  if (nodeIDs.length === 0) {
937
1048
  return state;
@@ -969,10 +1080,306 @@ function applyLayoutPresetToNodes(state, inputNodeIDs, preset) {
969
1080
  };
970
1081
  });
971
1082
  let nodeStack = state.nodeStack;
972
- for (const nodeID of nodeIDs) {
973
- nodeStack = focusWorkbenchStack(nodeStack, nodeID);
1083
+ if (options.reorderStack !== false) {
1084
+ for (const nodeID of nodeIDs) {
1085
+ nodeStack = focusWorkbenchStack(nodeStack, nodeID);
1086
+ }
1087
+ }
1088
+ const lockedLayout = options.lock ? { preset, nodeIDs } : null;
1089
+ return { ...state, nodes, nodeStack, lockedLayout };
1090
+ }
1091
+ function isLockedLayoutNode(state, nodeID) {
1092
+ return state.lockedLayout?.nodeIDs.includes(nodeID) ?? false;
1093
+ }
1094
+ function settleLockedDrag(state, nodeID) {
1095
+ const lockedLayout = state.lockedLayout;
1096
+ if (!lockedLayout || !lockedLayout.nodeIDs.includes(nodeID)) {
1097
+ return state;
1098
+ }
1099
+ const draggedNode = state.nodes.find((node) => node.id === nodeID);
1100
+ if (!draggedNode) {
1101
+ return state;
1102
+ }
1103
+ const draggedCenter = {
1104
+ x: draggedNode.frame.x + draggedNode.frame.width / 2,
1105
+ y: draggedNode.frame.y + draggedNode.frame.height / 2
1106
+ };
1107
+ const targetNode = state.nodes.find(
1108
+ (node) => node.id !== nodeID && !node.isMinimized && lockedLayout.nodeIDs.includes(node.id) && frameContainsPoint(node.frame, draggedCenter)
1109
+ );
1110
+ return applyLockedArrangement(
1111
+ state,
1112
+ lockedLayout,
1113
+ targetNode ? { firstID: nodeID, secondID: targetNode.id } : null
1114
+ );
1115
+ }
1116
+ function moveLockedNode(state, nodeID, direction) {
1117
+ const lockedLayout = state.lockedLayout;
1118
+ if (!lockedLayout || !lockedLayout.nodeIDs.includes(nodeID)) {
1119
+ return state;
1120
+ }
1121
+ const sourceNode = state.nodes.find((node) => node.id === nodeID);
1122
+ if (!sourceNode) {
1123
+ return state;
1124
+ }
1125
+ const sourceCenter = frameCenter(sourceNode.frame);
1126
+ let targetID = null;
1127
+ let bestScore = Number.POSITIVE_INFINITY;
1128
+ for (const node of state.nodes) {
1129
+ if (node.id === nodeID || node.isMinimized || !lockedLayout.nodeIDs.includes(node.id)) {
1130
+ continue;
1131
+ }
1132
+ const center = frameCenter(node.frame);
1133
+ const dx = center.x - sourceCenter.x;
1134
+ const dy = center.y - sourceCenter.y;
1135
+ const primary = direction === "left" ? -dx : direction === "right" ? dx : direction === "up" ? -dy : dy;
1136
+ if (primary <= 0.5) {
1137
+ continue;
1138
+ }
1139
+ const secondary = direction === "left" || direction === "right" ? Math.abs(dy) : Math.abs(dx);
1140
+ const score = primary + secondary * 2;
1141
+ if (score < bestScore) {
1142
+ bestScore = score;
1143
+ targetID = node.id;
1144
+ }
1145
+ }
1146
+ if (targetID === null) {
1147
+ return state;
974
1148
  }
975
- return { ...state, nodes, nodeStack };
1149
+ return applyLockedArrangement(state, lockedLayout, {
1150
+ firstID: nodeID,
1151
+ secondID: targetID
1152
+ });
1153
+ }
1154
+ function applyLockedArrangement(state, lockedLayout, swap) {
1155
+ const nodeIDs = swap ? swapNodeIDs(lockedLayout.nodeIDs, swap.firstID, swap.secondID) : lockedLayout.nodeIDs;
1156
+ if (lockedLayout.normalizedFrames) {
1157
+ let normalizedFrames = lockedLayout.normalizedFrames;
1158
+ if (swap) {
1159
+ const first = normalizedFrames[swap.firstID];
1160
+ const second = normalizedFrames[swap.secondID];
1161
+ if (first && second) {
1162
+ normalizedFrames = {
1163
+ ...normalizedFrames,
1164
+ [swap.firstID]: second,
1165
+ [swap.secondID]: first
1166
+ };
1167
+ }
1168
+ }
1169
+ return materializeLockedFrames(state, {
1170
+ ...lockedLayout,
1171
+ nodeIDs,
1172
+ normalizedFrames
1173
+ });
1174
+ }
1175
+ return applyLayoutPresetToNodes(state, nodeIDs, lockedLayout.preset, {
1176
+ lock: true,
1177
+ reorderStack: false
1178
+ });
1179
+ }
1180
+ function materializeLockedFrames(state, lockedLayout) {
1181
+ const normalizedFrames = lockedLayout.normalizedFrames;
1182
+ if (!normalizedFrames) {
1183
+ return { ...state, lockedLayout };
1184
+ }
1185
+ const layoutRect = getWorkbenchSafeLayoutRect(
1186
+ state.surfaceSize,
1187
+ state.layoutConstraints
1188
+ );
1189
+ const lockedNodeIDs = new Set(lockedLayout.nodeIDs);
1190
+ const nodes = state.nodes.map((node) => {
1191
+ const normalized = normalizedFrames[node.id];
1192
+ if (!normalized || !lockedNodeIDs.has(node.id)) {
1193
+ return node;
1194
+ }
1195
+ const frame = clampWorkbenchRect(
1196
+ denormalizeWorkbenchFrameFromRect(normalized, layoutRect),
1197
+ state.surfaceSize,
1198
+ state.layoutConstraints,
1199
+ node.sizeConstraints
1200
+ );
1201
+ if (node.displayMode === "floating" && !node.isMinimized && node.restoreFrame === null && rectsEqual(node.frame, frame)) {
1202
+ return node;
1203
+ }
1204
+ return {
1205
+ ...node,
1206
+ frame,
1207
+ displayMode: "floating",
1208
+ restoreFrame: null,
1209
+ isMinimized: false,
1210
+ minimizedAtUnixMs: null
1211
+ };
1212
+ });
1213
+ return { ...state, nodes, lockedLayout };
1214
+ }
1215
+ function resizeLockedGrid(state, nodeID, requestedFrame) {
1216
+ const lockedLayout = state.lockedLayout;
1217
+ if (!lockedLayout) {
1218
+ return state;
1219
+ }
1220
+ const sourceNode = state.nodes.find((node) => node.id === nodeID);
1221
+ if (!sourceNode) {
1222
+ return state;
1223
+ }
1224
+ const layoutRect = getWorkbenchSafeLayoutRect(
1225
+ state.surfaceSize,
1226
+ state.layoutConstraints
1227
+ );
1228
+ const lockedNodeIDs = lockedLayout.nodeIDs.filter(
1229
+ (lockedID) => state.nodes.some((node) => node.id === lockedID)
1230
+ );
1231
+ const frameByNodeID = new Map(
1232
+ state.nodes.filter((node) => lockedNodeIDs.includes(node.id)).map((node) => [
1233
+ node.id,
1234
+ {
1235
+ x: node.frame.x,
1236
+ y: node.frame.y,
1237
+ width: node.frame.width,
1238
+ height: node.frame.height
1239
+ }
1240
+ ])
1241
+ );
1242
+ const minSizeByNodeID = new Map(
1243
+ state.nodes.filter((node) => lockedNodeIDs.includes(node.id)).map(
1244
+ (node) => [
1245
+ node.id,
1246
+ {
1247
+ minWidth: Math.max(
1248
+ state.layoutConstraints.minWidth,
1249
+ node.sizeConstraints?.minWidth ?? 0
1250
+ ),
1251
+ minHeight: Math.max(
1252
+ state.layoutConstraints.minHeight,
1253
+ node.sizeConstraints?.minHeight ?? 0
1254
+ )
1255
+ }
1256
+ ]
1257
+ )
1258
+ );
1259
+ const oldFrame = sourceNode.frame;
1260
+ let changed = false;
1261
+ const dividerMoves = [
1262
+ { axis: "x", from: oldFrame.x, to: requestedFrame.x },
1263
+ {
1264
+ axis: "x",
1265
+ from: oldFrame.x + oldFrame.width,
1266
+ to: requestedFrame.x + requestedFrame.width
1267
+ },
1268
+ { axis: "y", from: oldFrame.y, to: requestedFrame.y },
1269
+ {
1270
+ axis: "y",
1271
+ from: oldFrame.y + oldFrame.height,
1272
+ to: requestedFrame.y + requestedFrame.height
1273
+ }
1274
+ ].filter((move) => Math.abs(move.to - move.from) > 0.1);
1275
+ const edgeTolerance = 2;
1276
+ const gapTolerance = WORKBENCH_LAYOUT_PRESET_GAP_PX + edgeTolerance;
1277
+ for (const move of dividerMoves) {
1278
+ const rectStart = move.axis === "x" ? layoutRect.x : layoutRect.y;
1279
+ const rectEnd = move.axis === "x" ? layoutRect.x + layoutRect.width : layoutRect.y + layoutRect.height;
1280
+ if (move.from - rectStart <= gapTolerance || rectEnd - move.from <= gapTolerance) {
1281
+ continue;
1282
+ }
1283
+ const trailing = [];
1284
+ const leading = [];
1285
+ let minDelta = Number.NEGATIVE_INFINITY;
1286
+ let maxDelta = Number.POSITIVE_INFINITY;
1287
+ for (const [lockedID, frame] of frameByNodeID) {
1288
+ const minSize = minSizeByNodeID.get(lockedID);
1289
+ const start = move.axis === "x" ? frame.x : frame.y;
1290
+ const size = move.axis === "x" ? frame.width : frame.height;
1291
+ const minLength = move.axis === "x" ? minSize.minWidth : minSize.minHeight;
1292
+ const endOffset = move.from - (start + size);
1293
+ const startOffset = start - move.from;
1294
+ if (endOffset >= -edgeTolerance && endOffset <= gapTolerance) {
1295
+ trailing.push(lockedID);
1296
+ minDelta = Math.max(minDelta, minLength - size);
1297
+ maxDelta = Math.min(maxDelta, rectEnd - (start + size));
1298
+ } else if (startOffset >= -edgeTolerance && startOffset <= gapTolerance) {
1299
+ leading.push(lockedID);
1300
+ maxDelta = Math.min(maxDelta, size - minLength);
1301
+ minDelta = Math.max(minDelta, rectStart - start);
1302
+ }
1303
+ }
1304
+ if (trailing.length === 0 && leading.length === 0) {
1305
+ continue;
1306
+ }
1307
+ const delta = Math.min(Math.max(move.to - move.from, minDelta), maxDelta);
1308
+ if (Math.abs(delta) <= 0.1) {
1309
+ continue;
1310
+ }
1311
+ for (const lockedID of trailing) {
1312
+ const frame = frameByNodeID.get(lockedID);
1313
+ if (move.axis === "x") {
1314
+ frame.width += delta;
1315
+ } else {
1316
+ frame.height += delta;
1317
+ }
1318
+ }
1319
+ for (const lockedID of leading) {
1320
+ const frame = frameByNodeID.get(lockedID);
1321
+ if (move.axis === "x") {
1322
+ frame.x += delta;
1323
+ frame.width -= delta;
1324
+ } else {
1325
+ frame.y += delta;
1326
+ frame.height -= delta;
1327
+ }
1328
+ }
1329
+ changed = true;
1330
+ }
1331
+ if (!changed) {
1332
+ return state;
1333
+ }
1334
+ const normalizedFrames = {};
1335
+ for (const [lockedID, frame] of frameByNodeID) {
1336
+ normalizedFrames[lockedID] = normalizeWorkbenchFrameToRect(
1337
+ frame,
1338
+ layoutRect
1339
+ );
1340
+ }
1341
+ const nodes = state.nodes.map((node) => {
1342
+ const frame = frameByNodeID.get(node.id);
1343
+ if (!frame || rectsEqual(node.frame, frame)) {
1344
+ return node;
1345
+ }
1346
+ return { ...node, frame };
1347
+ });
1348
+ return {
1349
+ ...state,
1350
+ nodes,
1351
+ nodeStack: focusWorkbenchStack(state.nodeStack, nodeID),
1352
+ lockedLayout: { ...lockedLayout, normalizedFrames }
1353
+ };
1354
+ }
1355
+ function swapNodeIDs(nodeIDs, firstID, secondID) {
1356
+ return nodeIDs.map(
1357
+ (entry) => entry === firstID ? secondID : entry === secondID ? firstID : entry
1358
+ );
1359
+ }
1360
+ function frameCenter(frame) {
1361
+ return {
1362
+ x: frame.x + frame.width / 2,
1363
+ y: frame.y + frame.height / 2
1364
+ };
1365
+ }
1366
+ function frameContainsPoint(frame, point) {
1367
+ return point.x >= frame.x && point.x <= frame.x + frame.width && point.y >= frame.y && point.y <= frame.y + frame.height;
1368
+ }
1369
+ function releaseLockedLayout(previousState, nextState) {
1370
+ if (nextState === previousState || nextState.lockedLayout === null) {
1371
+ return nextState;
1372
+ }
1373
+ return { ...nextState, lockedLayout: null };
1374
+ }
1375
+ function pruneLockedLayout(lockedLayout, removedNodeID) {
1376
+ if (!lockedLayout || !lockedLayout.nodeIDs.includes(removedNodeID)) {
1377
+ return lockedLayout;
1378
+ }
1379
+ const nodeIDs = lockedLayout.nodeIDs.filter(
1380
+ (nodeID) => nodeID !== removedNodeID
1381
+ );
1382
+ return nodeIDs.length >= 2 ? { preset: lockedLayout.preset, nodeIDs } : null;
976
1383
  }
977
1384
  function uniqueKnownNodeIDs(nodes, nodeIDs) {
978
1385
  const knownNodeIDs = new Set(nodes.map((node) => node.id));
@@ -1151,10 +1558,11 @@ function createWorkbenchController(initialState = {}, options = {}) {
1151
1558
  }
1152
1559
 
1153
1560
  // src/host/WorkbenchHost.tsx
1154
- import { useMemo as useMemo7 } from "react";
1561
+ import { useMemo as useMemo8 } from "react";
1155
1562
 
1156
1563
  // src/mission-control/WorkbenchMissionControlOverlay.tsx
1157
1564
  import {
1565
+ useEffect,
1158
1566
  useLayoutEffect,
1159
1567
  useRef,
1160
1568
  useState
@@ -1162,6 +1570,10 @@ import {
1162
1570
  import {
1163
1571
  AppWindowIcon,
1164
1572
  Button,
1573
+ DropdownMenu,
1574
+ DropdownMenuContent,
1575
+ DropdownMenuItem,
1576
+ DropdownMenuTrigger,
1165
1577
  GridHorizontalLinedIcon,
1166
1578
  GridVerticalLinedIcon
1167
1579
  } from "@tutti-os/ui-system";
@@ -1184,7 +1596,7 @@ function shouldShowWorkbenchMissionControlLayoutPreset(selectedCount, preset) {
1184
1596
  }
1185
1597
 
1186
1598
  // src/mission-control/WorkbenchMissionControlOverlay.tsx
1187
- import { jsx } from "react/jsx-runtime";
1599
+ import { jsx, jsxs } from "react/jsx-runtime";
1188
1600
  function WorkbenchMissionControlBackdrop({
1189
1601
  className,
1190
1602
  onExitTransitionComplete,
@@ -1212,6 +1624,30 @@ function WorkbenchMissionControlOverlay({
1212
1624
  }) {
1213
1625
  const layoutDockContentRef = useRef(null);
1214
1626
  const [layoutDockWidth, setLayoutDockWidth] = useState(null);
1627
+ const [openLayoutKey, setOpenLayoutKey] = useState(null);
1628
+ const hoverOpenTimeoutRef = useRef(null);
1629
+ const clearHoverOpenTimeout = () => {
1630
+ if (hoverOpenTimeoutRef.current !== null) {
1631
+ window.clearTimeout(hoverOpenTimeoutRef.current);
1632
+ hoverOpenTimeoutRef.current = null;
1633
+ }
1634
+ };
1635
+ const requestHoverOpen = (key) => {
1636
+ clearHoverOpenTimeout();
1637
+ if (openLayoutKey !== null) {
1638
+ setOpenLayoutKey(key);
1639
+ return;
1640
+ }
1641
+ hoverOpenTimeoutRef.current = window.setTimeout(() => {
1642
+ hoverOpenTimeoutRef.current = null;
1643
+ setOpenLayoutKey(key);
1644
+ }, layoutPresetMenuHoverOpenDelayMs);
1645
+ };
1646
+ const closeLayoutMenu = (key) => {
1647
+ clearHoverOpenTimeout();
1648
+ setOpenLayoutKey((current) => current === key ? null : current);
1649
+ };
1650
+ useEffect(() => clearHoverOpenTimeout, []);
1215
1651
  const layoutPresets = [
1216
1652
  {
1217
1653
  icon: AppWindowIcon,
@@ -1278,32 +1714,26 @@ function WorkbenchMissionControlOverlay({
1278
1714
  {
1279
1715
  ref: layoutDockContentRef,
1280
1716
  className: "workbench-mission-control__layout-dock-content",
1281
- children: showLayoutSelectionHint ? /* @__PURE__ */ jsx("span", { className: "workbench-mission-control__layout-hint", children: i18n.t("layoutSelectionHint") }) : showNoAvailableLayoutMessage ? /* @__PURE__ */ jsx("span", { className: "workbench-mission-control__layout-hint", children: i18n.t("noAvailableLayout") }) : /* @__PURE__ */ jsx("div", { className: "flex items-end gap-2", children: layoutPresets.map((option) => {
1282
- const canApply = state.canApplyPreset(option.preset);
1283
- const LayoutIcon = option.icon;
1284
- return /* @__PURE__ */ jsx(
1285
- Button,
1286
- {
1287
- "aria-label": option.label,
1288
- className: "workbench-mission-control__layout-dock-button",
1289
- "data-layout-key": option.key,
1290
- disabled: !canApply,
1291
- size: "icon",
1292
- title: option.label,
1293
- type: "button",
1294
- variant: "ghost",
1295
- onClick: () => state.applyPreset(option.preset),
1296
- children: /* @__PURE__ */ jsx(
1297
- LayoutIcon,
1298
- {
1299
- "aria-hidden": true,
1300
- className: "workbench-mission-control__layout-glyph"
1301
- }
1302
- )
1717
+ children: showLayoutSelectionHint ? /* @__PURE__ */ jsx("span", { className: "workbench-mission-control__layout-hint", children: i18n.t("layoutSelectionHint") }) : showNoAvailableLayoutMessage ? /* @__PURE__ */ jsx("span", { className: "workbench-mission-control__layout-hint", children: i18n.t("noAvailableLayout") }) : /* @__PURE__ */ jsx("div", { className: "flex items-end gap-2", children: layoutPresets.map((option) => /* @__PURE__ */ jsx(
1718
+ WorkbenchMissionControlLayoutPresetButton,
1719
+ {
1720
+ arrangeOnceLabel: i18n.t("presetActions.arrangeOnce"),
1721
+ canApply: state.canApplyPreset(option.preset),
1722
+ icon: option.icon,
1723
+ layoutKey: option.key,
1724
+ lockLayoutLabel: i18n.t("presetActions.lockLayout"),
1725
+ open: openLayoutKey === option.key,
1726
+ onApply: (lock) => {
1727
+ closeLayoutMenu(option.key);
1728
+ state.applyPreset(option.preset, { lock });
1303
1729
  },
1304
- option.key
1305
- );
1306
- }) })
1730
+ onHoverOpen: () => requestHoverOpen(option.key),
1731
+ onHoverCancel: clearHoverOpenTimeout,
1732
+ onRequestClose: () => closeLayoutMenu(option.key),
1733
+ presetLabel: option.label
1734
+ },
1735
+ option.key
1736
+ )) })
1307
1737
  }
1308
1738
  )
1309
1739
  }
@@ -1311,6 +1741,86 @@ function WorkbenchMissionControlOverlay({
1311
1741
  }
1312
1742
  );
1313
1743
  }
1744
+ var layoutPresetMenuHoverOpenDelayMs = 200;
1745
+ function WorkbenchMissionControlLayoutPresetButton({
1746
+ arrangeOnceLabel,
1747
+ canApply,
1748
+ icon: LayoutIcon,
1749
+ layoutKey,
1750
+ lockLayoutLabel,
1751
+ onApply,
1752
+ onHoverCancel,
1753
+ onHoverOpen,
1754
+ onRequestClose,
1755
+ open,
1756
+ presetLabel
1757
+ }) {
1758
+ return /* @__PURE__ */ jsxs(
1759
+ DropdownMenu,
1760
+ {
1761
+ open,
1762
+ onOpenChange: (nextOpen) => {
1763
+ if (!nextOpen) {
1764
+ onRequestClose();
1765
+ return;
1766
+ }
1767
+ if (canApply) {
1768
+ onHoverOpen();
1769
+ }
1770
+ },
1771
+ children: [
1772
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1773
+ Button,
1774
+ {
1775
+ "aria-label": presetLabel,
1776
+ className: "workbench-mission-control__layout-dock-button",
1777
+ "data-layout-key": layoutKey,
1778
+ "data-menu-open": open ? "true" : void 0,
1779
+ disabled: !canApply,
1780
+ size: "icon",
1781
+ title: presetLabel,
1782
+ type: "button",
1783
+ variant: "ghost",
1784
+ onClick: () => {
1785
+ if (canApply) {
1786
+ onApply(true);
1787
+ }
1788
+ },
1789
+ onPointerDown: (event) => {
1790
+ event.preventDefault();
1791
+ },
1792
+ onPointerEnter: () => {
1793
+ if (canApply) {
1794
+ onHoverOpen();
1795
+ }
1796
+ },
1797
+ onPointerLeave: onHoverCancel,
1798
+ children: /* @__PURE__ */ jsx(
1799
+ LayoutIcon,
1800
+ {
1801
+ "aria-hidden": true,
1802
+ className: "workbench-mission-control__layout-glyph"
1803
+ }
1804
+ )
1805
+ }
1806
+ ) }),
1807
+ /* @__PURE__ */ jsxs(
1808
+ DropdownMenuContent,
1809
+ {
1810
+ align: "center",
1811
+ className: "w-auto min-w-40",
1812
+ sideOffset: 10,
1813
+ onCloseAutoFocus: (event) => event.preventDefault(),
1814
+ children: [
1815
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => onApply(false), children: arrangeOnceLabel }),
1816
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => onApply(true), children: lockLayoutLabel })
1817
+ ]
1818
+ }
1819
+ )
1820
+ ]
1821
+ }
1822
+ );
1823
+ }
1314
1824
 
1315
1825
  // src/mission-control/useWorkbenchMissionControlPresence.ts
1316
1826
  import { useCallback, useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState as useState2 } from "react";
@@ -1373,7 +1883,7 @@ function useWorkbenchMissionControlPresence(state) {
1373
1883
  }
1374
1884
 
1375
1885
  // src/mission-control/useWorkbenchMissionControlState.ts
1376
- import { useCallback as useCallback2, useEffect, useMemo, useState as useState3 } from "react";
1886
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState3 } from "react";
1377
1887
  import {
1378
1888
  useExternalStoreSnapshot
1379
1889
  } from "@tutti-os/ui-react-hooks";
@@ -1560,13 +2070,13 @@ function useWorkbenchMissionControlState({
1560
2070
  return nextVisibleNodes.filter((node) => scopedNodeIdSet.has(node.id));
1561
2071
  }, [scopedNodeIdSet, snapshot?.visibleNodes]);
1562
2072
  const [selectedNodeIds, setSelectedNodeIds] = useState3([]);
1563
- useEffect(() => {
2073
+ useEffect2(() => {
1564
2074
  if (mode === null) {
1565
2075
  return;
1566
2076
  }
1567
2077
  setSelectedNodeIds([]);
1568
2078
  }, [mode]);
1569
- useEffect(() => {
2079
+ useEffect2(() => {
1570
2080
  if (mode !== null && visibleNodes.length === 0) {
1571
2081
  onRequestClose();
1572
2082
  }
@@ -1637,13 +2147,13 @@ function useWorkbenchMissionControlState({
1637
2147
  [adapter, onRequestClose]
1638
2148
  );
1639
2149
  const applyLayoutAndClose = useCallback2(
1640
- (nodeIds2, nextPreset) => {
2150
+ (nodeIds2, nextPreset, lock) => {
1641
2151
  if (!adapter || nodeIds2.length < 2) {
1642
2152
  return;
1643
2153
  }
1644
2154
  onRequestClose();
1645
2155
  window.requestAnimationFrame(() => {
1646
- adapter.applyLayoutPreset(nodeIds2, nextPreset);
2156
+ adapter.applyLayoutPreset(nodeIds2, nextPreset, lock);
1647
2157
  });
1648
2158
  },
1649
2159
  [adapter, onRequestClose]
@@ -1668,11 +2178,15 @@ function useWorkbenchMissionControlState({
1668
2178
  [selectedNodeIds]
1669
2179
  );
1670
2180
  const applyPreset = useCallback2(
1671
- (nextPreset) => {
2181
+ (nextPreset, options) => {
1672
2182
  if (!canApplyPreset(nextPreset)) {
1673
2183
  return;
1674
2184
  }
1675
- applyLayoutAndClose(orderedSelectedNodeIds, nextPreset);
2185
+ applyLayoutAndClose(
2186
+ orderedSelectedNodeIds,
2187
+ nextPreset,
2188
+ options?.lock ?? false
2189
+ );
1676
2190
  },
1677
2191
  [applyLayoutAndClose, canApplyPreset, orderedSelectedNodeIds]
1678
2192
  );
@@ -1699,7 +2213,7 @@ function useWorkbenchMissionControlState({
1699
2213
  selectedNodeIdSet
1700
2214
  ]
1701
2215
  );
1702
- useEffect(() => {
2216
+ useEffect2(() => {
1703
2217
  if (mode === null) {
1704
2218
  return void 0;
1705
2219
  }
@@ -1730,7 +2244,7 @@ function useWorkbenchMissionControlState({
1730
2244
  // src/react/WorkbenchSurface.tsx
1731
2245
  import {
1732
2246
  useCallback as useCallback7,
1733
- useEffect as useEffect4
2247
+ useEffect as useEffect5
1734
2248
  } from "react";
1735
2249
 
1736
2250
  // src/react/WorkbenchDockFrame.tsx
@@ -1832,7 +2346,7 @@ function useWorkbenchSelector(selector) {
1832
2346
  }
1833
2347
 
1834
2348
  // src/react/WorkbenchDockFrame.tsx
1835
- import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
2349
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1836
2350
  function WorkbenchDockFrame({
1837
2351
  dockPlacement = "bottom",
1838
2352
  genie,
@@ -1869,7 +2383,7 @@ function WorkbenchDockFrame({
1869
2383
  if (!renderDock && minimizedNodes.length === 0) {
1870
2384
  return null;
1871
2385
  }
1872
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2386
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
1873
2387
  hasFullscreenNode ? /* @__PURE__ */ jsx3(
1874
2388
  "div",
1875
2389
  {
@@ -1926,8 +2440,44 @@ function mergePendingMinimizedDockNode(nodes, pendingNode) {
1926
2440
  return [...nodes.filter((node) => node.id !== pendingNode.id), pendingNode];
1927
2441
  }
1928
2442
 
2443
+ // src/react/WorkbenchLockedSlotLayer.tsx
2444
+ import { useMemo as useMemo3 } from "react";
2445
+ import { jsx as jsx4 } from "react/jsx-runtime";
2446
+ var selectLockedLayout = (state) => state.lockedLayout;
2447
+ var selectSurfaceSize = (state) => state.surfaceSize;
2448
+ var selectLayoutConstraints = (state) => state.layoutConstraints;
2449
+ function WorkbenchLockedSlotLayer() {
2450
+ const lockedLayout = useWorkbenchSelector(selectLockedLayout);
2451
+ const surfaceSize = useWorkbenchSelector(selectSurfaceSize);
2452
+ const layoutConstraints = useWorkbenchSelector(selectLayoutConstraints);
2453
+ const slots = useMemo3(
2454
+ () => getWorkbenchLockedSlotFrames(
2455
+ lockedLayout,
2456
+ surfaceSize,
2457
+ layoutConstraints
2458
+ ),
2459
+ [layoutConstraints, lockedLayout, surfaceSize]
2460
+ );
2461
+ if (!slots) {
2462
+ return null;
2463
+ }
2464
+ return /* @__PURE__ */ jsx4("div", { "aria-hidden": true, className: "workbench-locked-slot-layer", children: slots.map((slot) => /* @__PURE__ */ jsx4(
2465
+ "div",
2466
+ {
2467
+ className: "workbench-locked-slot",
2468
+ style: {
2469
+ left: slot.frame.x,
2470
+ top: slot.frame.y,
2471
+ width: slot.frame.width,
2472
+ height: slot.frame.height
2473
+ }
2474
+ },
2475
+ slot.nodeID
2476
+ )) });
2477
+ }
2478
+
1929
2479
  // src/react/WorkbenchNodeLayer.tsx
1930
- import { Fragment as Fragment3, memo, useMemo as useMemo3 } from "react";
2480
+ import { Fragment as Fragment3, memo, useMemo as useMemo4 } from "react";
1931
2481
  import { createPortal } from "react-dom";
1932
2482
 
1933
2483
  // src/react/WorkbenchWindowFrame.tsx
@@ -1942,7 +2492,7 @@ import {
1942
2492
  TooltipTrigger,
1943
2493
  WindowTrafficLightIcon
1944
2494
  } from "@tutti-os/ui-system";
1945
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
2495
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1946
2496
  function WorkbenchWindowTrafficLights({
1947
2497
  className,
1948
2498
  close,
@@ -1952,7 +2502,7 @@ function WorkbenchWindowTrafficLights({
1952
2502
  onPointerDown,
1953
2503
  ...props
1954
2504
  }) {
1955
- return /* @__PURE__ */ jsxs2(
2505
+ return /* @__PURE__ */ jsxs3(
1956
2506
  "div",
1957
2507
  {
1958
2508
  ...props,
@@ -1966,7 +2516,7 @@ function WorkbenchWindowTrafficLights({
1966
2516
  onPointerDown?.(event);
1967
2517
  },
1968
2518
  children: [
1969
- close ? /* @__PURE__ */ jsx4(
2519
+ close ? /* @__PURE__ */ jsx5(
1970
2520
  WorkbenchWindowTrafficLightButton,
1971
2521
  {
1972
2522
  action: "close",
@@ -1974,7 +2524,7 @@ function WorkbenchWindowTrafficLights({
1974
2524
  tone: "close"
1975
2525
  }
1976
2526
  ) : null,
1977
- minimize ? /* @__PURE__ */ jsx4(
2527
+ minimize ? /* @__PURE__ */ jsx5(
1978
2528
  WorkbenchWindowTrafficLightButton,
1979
2529
  {
1980
2530
  action: "minimize",
@@ -1982,7 +2532,7 @@ function WorkbenchWindowTrafficLights({
1982
2532
  tone: "minimize"
1983
2533
  }
1984
2534
  ) : null,
1985
- maximize ? /* @__PURE__ */ jsx4(
2535
+ maximize ? /* @__PURE__ */ jsx5(
1986
2536
  WorkbenchWindowTrafficLightButton,
1987
2537
  {
1988
2538
  action: "fullscreen",
@@ -2010,7 +2560,7 @@ function WorkbenchWindowTrafficLightButton({
2010
2560
  event.stopPropagation();
2011
2561
  };
2012
2562
  const iconName = tone === "maximize" ? input.pressed ? "unfullscreen" : "fullscreen" : tone;
2013
- const button = /* @__PURE__ */ jsx4(
2563
+ const button = /* @__PURE__ */ jsx5(
2014
2564
  "button",
2015
2565
  {
2016
2566
  "aria-label": input.label,
@@ -2023,7 +2573,7 @@ function WorkbenchWindowTrafficLightButton({
2023
2573
  onClick: handleClick,
2024
2574
  onDoubleClick: (event) => event.stopPropagation(),
2025
2575
  onPointerDown: stopPointer,
2026
- children: /* @__PURE__ */ jsx4(
2576
+ children: /* @__PURE__ */ jsx5(
2027
2577
  WindowTrafficLightIcon,
2028
2578
  {
2029
2579
  "aria-hidden": "true",
@@ -2034,14 +2584,14 @@ function WorkbenchWindowTrafficLightButton({
2034
2584
  )
2035
2585
  }
2036
2586
  );
2037
- return /* @__PURE__ */ jsx4(TooltipProvider, { delayDuration: 250, skipDelayDuration: 0, children: /* @__PURE__ */ jsxs2(Tooltip, { children: [
2038
- /* @__PURE__ */ jsx4(TooltipTrigger, { asChild: true, children: button }),
2039
- /* @__PURE__ */ jsx4(TooltipContent, { side: "bottom", children: input.label })
2587
+ return /* @__PURE__ */ jsx5(TooltipProvider, { delayDuration: 250, skipDelayDuration: 0, children: /* @__PURE__ */ jsxs3(Tooltip, { children: [
2588
+ /* @__PURE__ */ jsx5(TooltipTrigger, { asChild: true, children: button }),
2589
+ /* @__PURE__ */ jsx5(TooltipContent, { side: "bottom", children: input.label })
2040
2590
  ] }) });
2041
2591
  }
2042
2592
 
2043
2593
  // src/react/WorkbenchWindowFullscreenToggle.tsx
2044
- import { jsx as jsx5 } from "react/jsx-runtime";
2594
+ import { jsx as jsx6 } from "react/jsx-runtime";
2045
2595
  function WorkbenchWindowFullscreenToggle({
2046
2596
  controller,
2047
2597
  disabled = false,
@@ -2050,7 +2600,7 @@ function WorkbenchWindowFullscreenToggle({
2050
2600
  }) {
2051
2601
  const isFullscreen = node.displayMode === "fullscreen";
2052
2602
  const label = i18n.t(isFullscreen ? "exitFullscreen" : "enterFullscreen");
2053
- return /* @__PURE__ */ jsx5(
2603
+ return /* @__PURE__ */ jsx6(
2054
2604
  WorkbenchWindowTrafficLights,
2055
2605
  {
2056
2606
  maximize: {
@@ -2127,16 +2677,22 @@ function useWorkbenchDrag(node, options = {}) {
2127
2677
  controller.commands.setActiveDragNode(node.id);
2128
2678
  const origin = { x: event.clientX, y: event.clientY };
2129
2679
  const initialFrame = node.frame;
2680
+ const isLockedLayoutDrag = () => {
2681
+ const lockedLayout = controller.getSnapshot().lockedLayout;
2682
+ return lockedLayout !== null && lockedLayout.nodeIDs.includes(node.id);
2683
+ };
2130
2684
  const onPointerMove = (moveEvent) => {
2131
2685
  const nextFrame = {
2132
2686
  ...initialFrame,
2133
2687
  x: initialFrame.x + moveEvent.clientX - origin.x,
2134
2688
  y: initialFrame.y + moveEvent.clientY - origin.y
2135
2689
  };
2136
- updateSnap(
2137
- { x: moveEvent.clientX, y: moveEvent.clientY },
2138
- { edgeSnapEnabled }
2139
- );
2690
+ if (!isLockedLayoutDrag()) {
2691
+ updateSnap(
2692
+ { x: moveEvent.clientX, y: moveEvent.clientY },
2693
+ { edgeSnapEnabled }
2694
+ );
2695
+ }
2140
2696
  controller.commands.dragNode(node.id, nextFrame);
2141
2697
  };
2142
2698
  const clearListeners = () => {
@@ -2147,7 +2703,9 @@ function useWorkbenchDrag(node, options = {}) {
2147
2703
  window.removeEventListener("pointercancel", cancelDrag);
2148
2704
  };
2149
2705
  const finishDrag = (upEvent) => {
2150
- if (updateSnap(
2706
+ if (isLockedLayoutDrag()) {
2707
+ controller.commands.settleLockedDrag(node.id);
2708
+ } else if (updateSnap(
2151
2709
  { x: upEvent.clientX, y: upEvent.clientY },
2152
2710
  { edgeSnapEnabled }
2153
2711
  ) !== null) {
@@ -2156,6 +2714,9 @@ function useWorkbenchDrag(node, options = {}) {
2156
2714
  clearListeners();
2157
2715
  };
2158
2716
  const cancelDrag = () => {
2717
+ if (isLockedLayoutDrag()) {
2718
+ controller.commands.settleLockedDrag(node.id);
2719
+ }
2159
2720
  clearListeners();
2160
2721
  };
2161
2722
  window.addEventListener("pointermove", onPointerMove);
@@ -2264,7 +2825,7 @@ function resolveWorkbenchWindowHeader({
2264
2825
  }
2265
2826
 
2266
2827
  // src/react/WorkbenchWindowFrame.tsx
2267
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
2828
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
2268
2829
  var resizeHandles = [
2269
2830
  "north",
2270
2831
  "east",
@@ -2336,7 +2897,7 @@ function WorkbenchWindowFrame({
2336
2897
  genie.minimizeNodeToAnchor(nodeID, minimize);
2337
2898
  }
2338
2899
  };
2339
- const defaultActions = interactive ? /* @__PURE__ */ jsxs3(
2900
+ const defaultActions = interactive ? /* @__PURE__ */ jsxs4(
2340
2901
  "div",
2341
2902
  {
2342
2903
  className: "workbench-window__traffic-light-actions",
@@ -2352,7 +2913,7 @@ function WorkbenchWindowFrame({
2352
2913
  genie: genieControls,
2353
2914
  node
2354
2915
  }) : null,
2355
- /* @__PURE__ */ jsx6(
2916
+ /* @__PURE__ */ jsx7(
2356
2917
  WorkbenchWindowFullscreenToggle,
2357
2918
  {
2358
2919
  controller,
@@ -2393,7 +2954,7 @@ function WorkbenchWindowFrame({
2393
2954
  (presentationFrame.height - node.frame.height * presentationScale) / 2
2394
2955
  ) - node.frame.y : 0;
2395
2956
  const shellTransform = presentationMode === "mission-control" && presentationFrame ? `matrix(${presentationScale}, 0, 0, ${presentationScale}, ${presentationOffsetX}, ${presentationOffsetY})` : void 0;
2396
- return /* @__PURE__ */ jsxs3(
2957
+ return /* @__PURE__ */ jsxs4(
2397
2958
  "section",
2398
2959
  {
2399
2960
  "aria-hidden": hiddenMounted || isPresentationHidden ? true : void 0,
@@ -2421,8 +2982,8 @@ function WorkbenchWindowFrame({
2421
2982
  },
2422
2983
  onPointerDown: hiddenMounted || isPresentationHidden || !interactive || presentationMode === "mission-control" ? void 0 : () => controller.commands.focusNode(node.id),
2423
2984
  children: [
2424
- /* @__PURE__ */ jsxs3("div", { className: "workbench-window-shell__content", children: [
2425
- /* @__PURE__ */ jsxs3(
2985
+ /* @__PURE__ */ jsxs4("div", { className: "workbench-window-shell__content", children: [
2986
+ /* @__PURE__ */ jsxs4(
2426
2987
  "div",
2427
2988
  {
2428
2989
  className: "workbench-window",
@@ -2434,7 +2995,7 @@ function WorkbenchWindowFrame({
2434
2995
  "data-window-drag-state": isDragging ? "dragging" : "idle",
2435
2996
  "data-window-resize-state": isResizing ? "resizing" : "idle",
2436
2997
  children: [
2437
- /* @__PURE__ */ jsx6(
2998
+ /* @__PURE__ */ jsx7(
2438
2999
  "div",
2439
3000
  {
2440
3001
  className: [
@@ -2443,19 +3004,19 @@ function WorkbenchWindowFrame({
2443
3004
  ].filter(Boolean).join(" "),
2444
3005
  onDoubleClick: shouldRenderCustomHeader || !interactive ? void 0 : onHeaderDoubleClick,
2445
3006
  onPointerDown: shouldRenderCustomHeader || !interactive ? void 0 : onDragStart,
2446
- children: shouldRenderCustomHeader ? resolvedHeader.customHeader : /* @__PURE__ */ jsxs3(Fragment2, { children: [
3007
+ children: shouldRenderCustomHeader ? resolvedHeader.customHeader : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2447
3008
  defaultActions,
2448
- /* @__PURE__ */ jsx6("div", { className: "workbench-window__title", children: node.title })
3009
+ /* @__PURE__ */ jsx7("div", { className: "workbench-window__title", children: node.title })
2449
3010
  ] })
2450
3011
  }
2451
3012
  ),
2452
- /* @__PURE__ */ jsx6("div", { className: "workbench-window__body", children })
3013
+ /* @__PURE__ */ jsx7("div", { className: "workbench-window__body", children })
2453
3014
  ]
2454
3015
  }
2455
3016
  ),
2456
- node.displayMode === "floating" && !hiddenMounted && presentationMode !== "mission-control" && interactive ? resizeHandles.map((handle) => /* @__PURE__ */ jsx6(ResizeHandle, { handle, node }, handle)) : null
3017
+ node.displayMode === "floating" && !hiddenMounted && presentationMode !== "mission-control" && interactive ? resizeHandles.map((handle) => /* @__PURE__ */ jsx7(ResizeHandle, { handle, node }, handle)) : null
2457
3018
  ] }),
2458
- presentationInteraction ? /* @__PURE__ */ jsx6(
3019
+ presentationInteraction ? /* @__PURE__ */ jsx7(
2459
3020
  "button",
2460
3021
  {
2461
3022
  "aria-label": node.title,
@@ -2466,10 +3027,10 @@ function WorkbenchWindowFrame({
2466
3027
  event.stopPropagation();
2467
3028
  presentationInteraction.onNodePress(node.id);
2468
3029
  },
2469
- children: presentationInteraction.mode === "layout" && isMissionControlSelected ? /* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute inset-0 rounded-lg border-2 border-[var(--tutti-purple)] transition-[border-color,transform] duration-150 ease-out" }) : null
3030
+ children: presentationInteraction.mode === "layout" && isMissionControlSelected ? /* @__PURE__ */ jsx7("div", { className: "pointer-events-none absolute inset-0 rounded-lg border-2 border-[var(--tutti-purple)] transition-[border-color,transform] duration-150 ease-out" }) : null
2470
3031
  }
2471
3032
  ) : null,
2472
- presentationInteraction?.mode === "layout" && isMissionControlSelected ? /* @__PURE__ */ jsx6(
3033
+ presentationInteraction?.mode === "layout" && isMissionControlSelected ? /* @__PURE__ */ jsx7(
2473
3034
  Checkbox,
2474
3035
  {
2475
3036
  "aria-hidden": "true",
@@ -2487,7 +3048,7 @@ function ResizeHandle({
2487
3048
  node
2488
3049
  }) {
2489
3050
  const onPointerDown = useWorkbenchResize(node, handle);
2490
- return /* @__PURE__ */ jsx6(
3051
+ return /* @__PURE__ */ jsx7(
2491
3052
  "div",
2492
3053
  {
2493
3054
  className: "workbench-window__resize-handle",
@@ -2522,7 +3083,7 @@ function stringArraysEqual(left, right) {
2522
3083
  }
2523
3084
 
2524
3085
  // src/react/WorkbenchNodeLayer.tsx
2525
- import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
3086
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2526
3087
  function WorkbenchNodeLayer({
2527
3088
  genie,
2528
3089
  edgeSnapEnabled = false,
@@ -2538,7 +3099,7 @@ function WorkbenchNodeLayer({
2538
3099
  windowChromeMode,
2539
3100
  windowChromeI18n
2540
3101
  }) {
2541
- const selectRenderedNodeIDs = useMemo3(
3102
+ const selectRenderedNodeIDs = useMemo4(
2542
3103
  () => createRenderedWorkbenchNodeIDsSelector(shouldKeepMinimizedNodeMounted),
2543
3104
  [shouldKeepMinimizedNodeMounted]
2544
3105
  );
@@ -2570,7 +3131,7 @@ function WorkbenchNodeLayer({
2570
3131
  });
2571
3132
  const snapPreviewRect = useWorkbenchSelector(selectWorkbenchSnapPreviewRect);
2572
3133
  const presentationInteraction = interactive && presentation?.mode === "mission-control" ? presentation.interaction ?? null : null;
2573
- const dialogPopoverLayer = dialogPopoverNodeIDs.length > 0 ? /* @__PURE__ */ jsx7(
3134
+ const dialogPopoverLayer = dialogPopoverNodeIDs.length > 0 ? /* @__PURE__ */ jsx8(
2574
3135
  WorkbenchNodeLayerGroup,
2575
3136
  {
2576
3137
  className: "workbench-node-layer workbench-node-layer--dialog-popover",
@@ -2588,8 +3149,8 @@ function WorkbenchNodeLayer({
2588
3149
  windowChromeMode
2589
3150
  }
2590
3151
  ) : null;
2591
- return /* @__PURE__ */ jsxs4(Fragment3, { children: [
2592
- /* @__PURE__ */ jsx7(
3152
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
3153
+ /* @__PURE__ */ jsx8(
2593
3154
  WorkbenchNodeLayerGroup,
2594
3155
  {
2595
3156
  className: "workbench-node-layer",
@@ -2629,7 +3190,7 @@ function WorkbenchNodeLayerGroup({
2629
3190
  windowChromeI18n,
2630
3191
  windowChromeMode
2631
3192
  }) {
2632
- return /* @__PURE__ */ jsxs4(
3193
+ return /* @__PURE__ */ jsxs5(
2633
3194
  "div",
2634
3195
  {
2635
3196
  className,
@@ -2641,7 +3202,7 @@ function WorkbenchNodeLayerGroup({
2641
3202
  onBackdropPress();
2642
3203
  } : void 0,
2643
3204
  children: [
2644
- snapPreviewRect ? /* @__PURE__ */ jsx7(
3205
+ snapPreviewRect ? /* @__PURE__ */ jsx8(
2645
3206
  "div",
2646
3207
  {
2647
3208
  className: "workbench-snap-preview",
@@ -2653,7 +3214,7 @@ function WorkbenchNodeLayerGroup({
2653
3214
  }
2654
3215
  }
2655
3216
  ) : null,
2656
- nodeIDs.map((nodeID) => /* @__PURE__ */ jsx7(
3217
+ nodeIDs.map((nodeID) => /* @__PURE__ */ jsx8(
2657
3218
  MemoizedWorkbenchNodeLayerItem,
2658
3219
  {
2659
3220
  fullscreenHeaderMode,
@@ -2702,7 +3263,7 @@ function WorkbenchNodeLayerItem({
2702
3263
  if (!node) {
2703
3264
  return null;
2704
3265
  }
2705
- return /* @__PURE__ */ jsx7(
3266
+ return /* @__PURE__ */ jsx8(
2706
3267
  WorkbenchWindowFrame,
2707
3268
  {
2708
3269
  edgeSnapEnabled,
@@ -2742,7 +3303,7 @@ var MemoizedWorkbenchNodeLayerItem = memo(
2742
3303
  );
2743
3304
 
2744
3305
  // src/react/hooks/useWorkbenchShortcuts.ts
2745
- import { useEffect as useEffect2 } from "react";
3306
+ import { useEffect as useEffect3 } from "react";
2746
3307
 
2747
3308
  // src/react/hooks/workbenchShortcutIntent.ts
2748
3309
  function resolveWorkbenchShortcutIntent(event, options = {}) {
@@ -2801,7 +3362,7 @@ function useWorkbenchShortcuts(options = {}) {
2801
3362
  const controller = useWorkbenchController();
2802
3363
  const enabled = options.enabled ?? true;
2803
3364
  const windowManagementShortcutPreset = options.windowManagementShortcutPreset ?? null;
2804
- useEffect2(() => {
3365
+ useEffect3(() => {
2805
3366
  if (!enabled) {
2806
3367
  return void 0;
2807
3368
  }
@@ -2813,9 +3374,9 @@ function useWorkbenchShortcuts(options = {}) {
2813
3374
  return;
2814
3375
  }
2815
3376
  let handled = false;
2816
- const focusedNode = selectFocusedVisibleWorkbenchNode(
2817
- controller.getSnapshot()
2818
- );
3377
+ const snapshot = controller.getSnapshot();
3378
+ const focusedNode = selectFocusedVisibleWorkbenchNode(snapshot);
3379
+ const isLockedFocusedNode = focusedNode !== null && (snapshot.lockedLayout?.nodeIDs.includes(focusedNode.id) ?? false);
2819
3380
  if (intent.type === "exitFullscreen") {
2820
3381
  if (focusedNode?.displayMode === "fullscreen") {
2821
3382
  controller.commands.exitFullscreen(focusedNode.id);
@@ -2823,15 +3384,25 @@ function useWorkbenchShortcuts(options = {}) {
2823
3384
  }
2824
3385
  } else if (intent.type === "applyFocusedSnapTarget") {
2825
3386
  if (focusedNode) {
2826
- controller.commands.applySnapTarget(
2827
- focusedNode.id,
2828
- intent.snapTarget
2829
- );
3387
+ const lockedDirection = isLockedFocusedNode ? resolveLockedMoveDirection(intent.snapTarget) : null;
3388
+ if (lockedDirection) {
3389
+ controller.commands.moveLockedNode(focusedNode.id, lockedDirection);
3390
+ } else {
3391
+ controller.commands.applySnapTarget(
3392
+ focusedNode.id,
3393
+ intent.snapTarget
3394
+ );
3395
+ }
2830
3396
  handled = true;
2831
3397
  }
2832
3398
  } else if (intent.type === "applyFocusedQuickLayout") {
2833
3399
  if (focusedNode) {
2834
- controller.commands.applyQuickLayout(focusedNode.id, intent.target);
3400
+ const lockedDirection = isLockedFocusedNode ? resolveLockedMoveDirection(intent.target) : null;
3401
+ if (lockedDirection) {
3402
+ controller.commands.moveLockedNode(focusedNode.id, lockedDirection);
3403
+ } else {
3404
+ controller.commands.applyQuickLayout(focusedNode.id, intent.target);
3405
+ }
2835
3406
  handled = true;
2836
3407
  }
2837
3408
  } else {
@@ -2849,6 +3420,20 @@ function useWorkbenchShortcuts(options = {}) {
2849
3420
  };
2850
3421
  }, [controller, enabled, windowManagementShortcutPreset]);
2851
3422
  }
3423
+ function resolveLockedMoveDirection(target) {
3424
+ switch (target) {
3425
+ case "left":
3426
+ return "left";
3427
+ case "right":
3428
+ return "right";
3429
+ case "top":
3430
+ return "up";
3431
+ case "bottom":
3432
+ return "down";
3433
+ default:
3434
+ return null;
3435
+ }
3436
+ }
2852
3437
 
2853
3438
  // src/react/hooks/useWorkbenchSurfaceSize.ts
2854
3439
  import { useLayoutEffect as useLayoutEffect3, useRef as useRef3 } from "react";
@@ -2885,7 +3470,7 @@ function useWorkbenchSurfaceSize(onSizeChange) {
2885
3470
  // src/react/useWorkbenchGenieAnimation.tsx
2886
3471
  import {
2887
3472
  useCallback as useCallback6,
2888
- useEffect as useEffect3,
3473
+ useEffect as useEffect4,
2889
3474
  useRef as useRef4,
2890
3475
  useState as useState4
2891
3476
  } from "react";
@@ -3216,7 +3801,7 @@ function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
3216
3801
  }
3217
3802
 
3218
3803
  // src/react/useWorkbenchGenieAnimation.tsx
3219
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
3804
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
3220
3805
  var genieDurationMs = 400;
3221
3806
  var previewCaptureRaceTimeoutMs = 120;
3222
3807
  var scaleMinimizeDurationMs = 220;
@@ -4088,7 +4673,7 @@ function useWorkbenchGenieAnimation({
4088
4673
  },
4089
4674
  [stopAnimation]
4090
4675
  );
4091
- useEffect3(() => () => stopAnimation(false), [stopAnimation]);
4676
+ useEffect4(() => () => stopAnimation(false), [stopAnimation]);
4092
4677
  const startOpenOrRestoreAnimation = useCallback6(
4093
4678
  async (nodeID, anchorKey, generation, dockRectFallback, minimizedNode) => {
4094
4679
  const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
@@ -4735,7 +5320,7 @@ function useWorkbenchGenieAnimation({
4735
5320
  writeMinimizedGenieTexture
4736
5321
  ]
4737
5322
  );
4738
- useEffect3(
5323
+ useEffect4(
4739
5324
  () => () => {
4740
5325
  for (const timer of minimizedDockEnterAnimationTimersRef.current.values()) {
4741
5326
  clearTimeout(timer);
@@ -4748,8 +5333,8 @@ function useWorkbenchGenieAnimation({
4748
5333
  );
4749
5334
  return {
4750
5335
  genieLayer: typeof document === "undefined" ? null : createPortal2(
4751
- /* @__PURE__ */ jsxs5(Fragment4, { children: [
4752
- /* @__PURE__ */ jsx8(
5336
+ /* @__PURE__ */ jsxs6(Fragment4, { children: [
5337
+ /* @__PURE__ */ jsx9(
4753
5338
  "canvas",
4754
5339
  {
4755
5340
  ref: canvasRef,
@@ -4758,7 +5343,7 @@ function useWorkbenchGenieAnimation({
4758
5343
  "aria-hidden": true
4759
5344
  }
4760
5345
  ),
4761
- pendingRenderedPreviewCapture ? /* @__PURE__ */ jsx8(
5346
+ pendingRenderedPreviewCapture ? /* @__PURE__ */ jsx9(
4762
5347
  "div",
4763
5348
  {
4764
5349
  ref: renderedPreviewCaptureElementRef,
@@ -4794,7 +5379,7 @@ function useWorkbenchGenieAnimation({
4794
5379
  }
4795
5380
 
4796
5381
  // src/react/WorkbenchSurface.tsx
4797
- import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
5382
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
4798
5383
  function WorkbenchSurface({
4799
5384
  captureNodePreviewImage,
4800
5385
  className,
@@ -4829,7 +5414,7 @@ function WorkbenchSurface({
4829
5414
  windowChromeMode,
4830
5415
  windowChromeI18n
4831
5416
  }) {
4832
- return /* @__PURE__ */ jsx9(WorkbenchProvider, { controller, children: /* @__PURE__ */ jsx9(
5417
+ return /* @__PURE__ */ jsx10(WorkbenchProvider, { controller, children: /* @__PURE__ */ jsx10(
4833
5418
  WorkbenchSurfaceInner,
4834
5419
  {
4835
5420
  captureNodePreviewImage,
@@ -4922,7 +5507,7 @@ function WorkbenchSurfaceInner({
4922
5507
  enabled: (shortcutsEnabled ?? true) && interactive,
4923
5508
  windowManagementShortcutPreset: windowManagement?.shortcutPreset ?? null
4924
5509
  });
4925
- useEffect4(() => {
5510
+ useEffect5(() => {
4926
5511
  if (!layoutConstraints) {
4927
5512
  return;
4928
5513
  }
@@ -4935,7 +5520,7 @@ function WorkbenchSurfaceInner({
4935
5520
  wallpaper.fit ?? "cover"
4936
5521
  )
4937
5522
  } : void 0;
4938
- return /* @__PURE__ */ jsxs6(
5523
+ return /* @__PURE__ */ jsxs7(
4939
5524
  "div",
4940
5525
  {
4941
5526
  ref,
@@ -4944,7 +5529,7 @@ function WorkbenchSurfaceInner({
4944
5529
  "data-presentation-mode": presentation?.mode ?? "default",
4945
5530
  "data-workbench-interactive": interactive ? "true" : "false",
4946
5531
  children: [
4947
- wallpaper ? /* @__PURE__ */ jsx9(
5532
+ wallpaper ? /* @__PURE__ */ jsx10(
4948
5533
  "div",
4949
5534
  {
4950
5535
  className: "workbench-surface__wallpaper",
@@ -4952,9 +5537,10 @@ function WorkbenchSurfaceInner({
4952
5537
  "aria-hidden": true
4953
5538
  }
4954
5539
  ) : null,
4955
- renderTopChrome ? /* @__PURE__ */ jsx9("div", { className: "workbench-surface__top-chrome", children: renderTopChrome() }) : null,
5540
+ renderTopChrome ? /* @__PURE__ */ jsx10("div", { className: "workbench-surface__top-chrome", children: renderTopChrome() }) : null,
4956
5541
  renderBackdrop ? renderBackdrop() : null,
4957
- /* @__PURE__ */ jsx9(
5542
+ presentation?.mode === "mission-control" ? null : /* @__PURE__ */ jsx10(WorkbenchLockedSlotLayer, {}),
5543
+ /* @__PURE__ */ jsx10(
4958
5544
  WorkbenchNodeLayer,
4959
5545
  {
4960
5546
  genie,
@@ -4972,7 +5558,7 @@ function WorkbenchSurfaceInner({
4972
5558
  windowChromeI18n
4973
5559
  }
4974
5560
  ),
4975
- /* @__PURE__ */ jsx9(
5561
+ /* @__PURE__ */ jsx10(
4976
5562
  WorkbenchDockFrame,
4977
5563
  {
4978
5564
  dockPlacement,
@@ -4981,7 +5567,7 @@ function WorkbenchSurfaceInner({
4981
5567
  renderDock
4982
5568
  }
4983
5569
  ),
4984
- renderBottomChrome ? /* @__PURE__ */ jsx9("div", { className: "workbench-surface__bottom-chrome", children: renderBottomChrome() }) : null,
5570
+ renderBottomChrome ? /* @__PURE__ */ jsx10("div", { className: "workbench-surface__bottom-chrome", children: renderBottomChrome() }) : null,
4985
5571
  renderOverlay ? renderOverlay() : null,
4986
5572
  genie.genieLayer
4987
5573
  ]
@@ -5146,7 +5732,7 @@ function resolveHostClosePreparer(contributions) {
5146
5732
  }
5147
5733
 
5148
5734
  // src/host/useWorkbenchHostRuntime.ts
5149
- import { useEffect as useEffect5, useMemo as useMemo4, useState as useState5 } from "react";
5735
+ import { useEffect as useEffect6, useMemo as useMemo5, useState as useState5 } from "react";
5150
5736
 
5151
5737
  // src/store/createDerivedSnapshotGetter.ts
5152
5738
  function createDerivedSnapshotGetter(input) {
@@ -5184,8 +5770,8 @@ function createWorkbenchHostMissionControlAdapter(input) {
5184
5770
  }
5185
5771
  });
5186
5772
  return {
5187
- applyLayoutPreset(nodeIds, preset) {
5188
- input.controller.commands.applyLayoutPreset(nodeIds, preset);
5773
+ applyLayoutPreset(nodeIds, preset, lock) {
5774
+ input.controller.commands.applyLayoutPreset(nodeIds, preset, lock);
5189
5775
  },
5190
5776
  focusNode(nodeId) {
5191
5777
  if (input.activateNode) {
@@ -7028,7 +7614,7 @@ function useWorkbenchHostRuntime({
7028
7614
  }) {
7029
7615
  const [externalStateRevision, bumpExternalStateRevision] = useState5(0);
7030
7616
  const [, bumpHydrationRevision] = useState5(0);
7031
- const hostSession = useMemo4(() => {
7617
+ const hostSession = useMemo5(() => {
7032
7618
  logWorkbenchHostDebug("create-session", debugDiagnostics, {
7033
7619
  nodeTypeIDs: nodes.map((node) => node.typeId),
7034
7620
  projectedNodeCount: projectedNodes?.length ?? 0,
@@ -7053,32 +7639,32 @@ function useWorkbenchHostRuntime({
7053
7639
  snapshotRepository,
7054
7640
  workspaceId
7055
7641
  ]);
7056
- const hostI18n = useMemo4(() => createWorkbenchHostI18nRuntime(i18n), [i18n]);
7057
- const missionControlI18n = useMemo4(
7642
+ const hostI18n = useMemo5(() => createWorkbenchHostI18nRuntime(i18n), [i18n]);
7643
+ const missionControlI18n = useMemo5(
7058
7644
  () => createWorkbenchMissionControlI18nRuntime(i18n),
7059
7645
  [i18n]
7060
7646
  );
7061
- const windowChromeI18n = useMemo4(
7647
+ const windowChromeI18n = useMemo5(
7062
7648
  () => createWorkbenchWindowChromeI18nRuntime(i18n),
7063
7649
  [i18n]
7064
7650
  );
7065
- const nodeDefinitionByType = useMemo4(
7651
+ const nodeDefinitionByType = useMemo5(
7066
7652
  () => new Map(nodes.map((definition) => [definition.typeId, definition])),
7067
7653
  [nodes]
7068
7654
  );
7069
7655
  const isHydrating = hostSession.isHydrating?.() ?? false;
7070
- const missionControlAdapter = useMemo4(
7656
+ const missionControlAdapter = useMemo5(
7071
7657
  () => missionControlEnabled && !isHydrating ? createWorkbenchHostMissionControlAdapter({
7072
7658
  activateNode: hostSession.activateNode.bind(hostSession),
7073
7659
  controller: hostSession.controller
7074
7660
  }) : null,
7075
7661
  [hostSession.controller, isHydrating, missionControlEnabled]
7076
7662
  );
7077
- const chromeController = useMemo4(
7663
+ const chromeController = useMemo5(
7078
7664
  () => isHydrating ? createReadOnlyWorkbenchController(hostSession.controller) : hostSession.controller,
7079
7665
  [hostSession.controller, isHydrating]
7080
7666
  );
7081
- const chromeContext = useMemo4(
7667
+ const chromeContext = useMemo5(
7082
7668
  () => ({
7083
7669
  activateNode: hostSession.activateNode.bind(hostSession),
7084
7670
  controller: chromeController,
@@ -7087,7 +7673,7 @@ function useWorkbenchHostRuntime({
7087
7673
  }),
7088
7674
  [chromeController, hostSession]
7089
7675
  );
7090
- useEffect5(() => {
7676
+ useEffect6(() => {
7091
7677
  let isCurrent = true;
7092
7678
  void hostSession.load().finally(() => {
7093
7679
  if (isCurrent) {
@@ -7102,13 +7688,13 @@ function useWorkbenchHostRuntime({
7102
7688
  hostSession.dispose();
7103
7689
  };
7104
7690
  }, [debugDiagnostics, hostSession, workspaceId]);
7105
- useEffect5(() => {
7691
+ useEffect6(() => {
7106
7692
  onHandleReady?.(hostSession);
7107
7693
  return () => {
7108
7694
  onHandleReady?.(null);
7109
7695
  };
7110
7696
  }, [hostSession, onHandleReady]);
7111
- useEffect5(() => {
7697
+ useEffect6(() => {
7112
7698
  if (!onMissionControlAdapterReady) {
7113
7699
  return void 0;
7114
7700
  }
@@ -7117,10 +7703,10 @@ function useWorkbenchHostRuntime({
7117
7703
  onMissionControlAdapterReady(null);
7118
7704
  };
7119
7705
  }, [missionControlAdapter, onMissionControlAdapterReady]);
7120
- useEffect5(() => {
7706
+ useEffect6(() => {
7121
7707
  hostSession.reconcileProjectedNodes(projectedNodes ?? []);
7122
7708
  }, [hostSession, projectedNodes]);
7123
- useEffect5(() => {
7709
+ useEffect6(() => {
7124
7710
  if (!externalStateSource?.subscribe) {
7125
7711
  return void 0;
7126
7712
  }
@@ -7176,14 +7762,14 @@ function logWorkbenchHostDebug(event, debugDiagnostics, payload) {
7176
7762
  }
7177
7763
 
7178
7764
  // src/host/useWorkbenchHostSurfaceRenderers.tsx
7179
- import { Component, useCallback as useCallback11, useMemo as useMemo6 } from "react";
7765
+ import { Component, useCallback as useCallback11, useMemo as useMemo7 } from "react";
7180
7766
 
7181
7767
  // src/host/WorkbenchHostDock.tsx
7182
7768
  import {
7183
7769
  useCallback as useCallback10,
7184
- useEffect as useEffect9,
7770
+ useEffect as useEffect10,
7185
7771
  useLayoutEffect as useLayoutEffect5,
7186
- useMemo as useMemo5,
7772
+ useMemo as useMemo6,
7187
7773
  useRef as useRef8,
7188
7774
  useState as useState8
7189
7775
  } from "react";
@@ -7288,7 +7874,7 @@ function isWorkbenchDockEntryBlocked(entry) {
7288
7874
  }
7289
7875
 
7290
7876
  // src/host/dockMagnification.ts
7291
- import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef5 } from "react";
7877
+ import { useCallback as useCallback8, useEffect as useEffect7, useRef as useRef5 } from "react";
7292
7878
 
7293
7879
  // src/host/dockMagnificationBounds.ts
7294
7880
  function resolveDockMagnificationViewportBounds(viewportRect, dockPlacement) {
@@ -7888,7 +8474,7 @@ function useDockMagnification({
7888
8474
  );
7889
8475
  handleGlobalPointerMoveRef.current = handlePointerMove;
7890
8476
  handleGlobalPointerCancelRef.current = handleGlobalPointerCancel;
7891
- useEffect6(() => {
8477
+ useEffect7(() => {
7892
8478
  if (typeof document === "undefined") {
7893
8479
  return;
7894
8480
  }
@@ -8016,7 +8602,7 @@ function useDockMagnification({
8016
8602
  entryRampStartedAtRef.current = null;
8017
8603
  setMagnifyActive(false);
8018
8604
  }, [setMagnifyActive, slotRefs, stopAnimation, stopGlobalPointerTracking]);
8019
- useEffect6(
8605
+ useEffect7(
8020
8606
  () => () => {
8021
8607
  resetMagnification();
8022
8608
  },
@@ -8122,7 +8708,7 @@ function orderWorkbenchMinimizedDockNodes(input) {
8122
8708
  }
8123
8709
 
8124
8710
  // src/host/minimizedDockStackPromotion.ts
8125
- import { useEffect as useEffect7, useRef as useRef6, useState as useState6 } from "react";
8711
+ import { useEffect as useEffect8, useRef as useRef6, useState as useState6 } from "react";
8126
8712
  var minimizedDockStackPromotionDurationMs = 520;
8127
8713
  function detectMinimizedDockStackPromotion(previous, next) {
8128
8714
  const previousVisibleNodeIds = new Set(
@@ -8146,7 +8732,7 @@ function useMinimizedDockStackPromotion(slots) {
8146
8732
  const promotionTimerRef = useRef6(null);
8147
8733
  const [promotedNodeId, setPromotedNodeId] = useState6(null);
8148
8734
  const [stackDispatching, setStackDispatching] = useState6(false);
8149
- useEffect7(() => {
8735
+ useEffect8(() => {
8150
8736
  const promotedNodeId2 = detectMinimizedDockStackPromotion(
8151
8737
  previousSlotsRef.current,
8152
8738
  slots
@@ -8213,7 +8799,7 @@ function resolveWorkbenchMinimizedDockRestoreIntent(input) {
8213
8799
  import {
8214
8800
  forwardRef,
8215
8801
  useCallback as useCallback9,
8216
- useEffect as useEffect8,
8802
+ useEffect as useEffect9,
8217
8803
  useLayoutEffect as useLayoutEffect4,
8218
8804
  useRef as useRef7,
8219
8805
  useState as useState7
@@ -8362,7 +8948,7 @@ function resolveMinimizedStackTrackTranslateXPx(input) {
8362
8948
  }
8363
8949
 
8364
8950
  // src/host/WorkbenchHostDockPopup.tsx
8365
- import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
8951
+ import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
8366
8952
  var dockPopupCardWidthPx = 165;
8367
8953
  var dockPopupGridGapPx = 8;
8368
8954
  var dockPopupPanelPaddingInlinePx = 12;
@@ -8540,7 +9126,7 @@ function WorkbenchHostDockPopup({
8540
9126
  } : {}
8541
9127
  };
8542
9128
  const popupDiagnosticKey = items.map((item) => item.node.id).join("|");
8543
- useEffect8(() => {
9129
+ useEffect9(() => {
8544
9130
  logWorkbenchDockPopupDebug("dock.popup.rendered", debugDiagnostics, {
8545
9131
  hasCapturePreview: Boolean(capturePreview),
8546
9132
  itemCount: popupDiagnosticKey ? popupDiagnosticKey.split("|").length : 0,
@@ -8583,7 +9169,7 @@ function WorkbenchHostDockPopup({
8583
9169
  cardRefCallbacksRef.current.set(nodeId, callback);
8584
9170
  return callback;
8585
9171
  }, []);
8586
- useEffect8(() => {
9172
+ useEffect9(() => {
8587
9173
  if (!isLeftMinimizedStack) {
8588
9174
  return;
8589
9175
  }
@@ -8595,7 +9181,7 @@ function WorkbenchHostDockPopup({
8595
9181
  document.body.removeAttribute("data-desktop-dock-minimized-stack-open");
8596
9182
  };
8597
9183
  }, [isLeftMinimizedStack]);
8598
- useEffect8(() => {
9184
+ useEffect9(() => {
8599
9185
  const handlePointerDown = (event) => {
8600
9186
  if (!(event.target instanceof Element)) {
8601
9187
  onClose();
@@ -8623,13 +9209,13 @@ function WorkbenchHostDockPopup({
8623
9209
  const previewCaptureKey = items.map(
8624
9210
  (item) => `${item.node.id}:${previewCacheToken(item.preview)}:${item.previewRevision ?? ""}`
8625
9211
  ).join("|");
8626
- useEffect8(() => {
9212
+ useEffect9(() => {
8627
9213
  if (!isMinimizedStack) {
8628
9214
  return;
8629
9215
  }
8630
9216
  setMinimizedStackScrollOffset(initialMinimizedStackScrollOffset);
8631
9217
  }, [initialMinimizedStackScrollOffset, isMinimizedStack, items.length]);
8632
- useEffect8(() => {
9218
+ useEffect9(() => {
8633
9219
  if (!isMinimizedStack) {
8634
9220
  return;
8635
9221
  }
@@ -8650,7 +9236,7 @@ function WorkbenchHostDockPopup({
8650
9236
  viewport.addEventListener("wheel", handleWheel, { passive: false });
8651
9237
  return () => viewport.removeEventListener("wheel", handleWheel);
8652
9238
  }, [isMinimizedStack, minimizedStackMaxScrollOffset]);
8653
- useEffect8(() => {
9239
+ useEffect9(() => {
8654
9240
  if (!capturePreview || isContextMenu) {
8655
9241
  return;
8656
9242
  }
@@ -8867,7 +9453,7 @@ function WorkbenchHostDockPopup({
8867
9453
  previewCaptureKey,
8868
9454
  resolveDockPreviewCacheKey2
8869
9455
  ]);
8870
- const content = /* @__PURE__ */ jsx10(
9456
+ const content = /* @__PURE__ */ jsx11(
8871
9457
  "div",
8872
9458
  {
8873
9459
  ref: popupRootRef,
@@ -8876,7 +9462,7 @@ function WorkbenchHostDockPopup({
8876
9462
  "data-desktop-dock-popup-root": "true",
8877
9463
  "data-popup-variant": resolvedVariant,
8878
9464
  style: popupStyle,
8879
- children: /* @__PURE__ */ jsx10(
9465
+ children: /* @__PURE__ */ jsx11(
8880
9466
  "div",
8881
9467
  {
8882
9468
  "aria-label": label,
@@ -8892,7 +9478,7 @@ function WorkbenchHostDockPopup({
8892
9478
  onPointerLeave: isMinimizedStack ? () => setPointer(null) : void 0,
8893
9479
  role: "dialog",
8894
9480
  style: panelStyle,
8895
- children: isContextMenu ? /* @__PURE__ */ jsx10(
9481
+ children: isContextMenu ? /* @__PURE__ */ jsx11(
8896
9482
  WorkbenchHostDockContextMenu,
8897
9483
  {
8898
9484
  canCreateNew: showCreateNew !== false,
@@ -8915,9 +9501,9 @@ function WorkbenchHostDockPopup({
8915
9501
  showAllWindowsLabel,
8916
9502
  showOpen: showOpen === true
8917
9503
  }
8918
- ) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
8919
- /* @__PURE__ */ jsx10("div", { className: "mb-2.5 flex items-center justify-between", children: /* @__PURE__ */ jsx10("span", { className: "min-w-0 truncate text-sm font-semibold", children: label }) }),
8920
- isMinimizedStack ? /* @__PURE__ */ jsx10(
9504
+ ) : /* @__PURE__ */ jsxs8(Fragment5, { children: [
9505
+ /* @__PURE__ */ jsx11("div", { className: "mb-2.5 flex items-center justify-between", children: /* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate text-sm font-semibold", children: label }) }),
9506
+ isMinimizedStack ? /* @__PURE__ */ jsx11(
8921
9507
  "div",
8922
9508
  {
8923
9509
  ref: minimizedStackViewportRef,
@@ -8926,7 +9512,7 @@ function WorkbenchHostDockPopup({
8926
9512
  height: minimizedStackViewportHeightPx,
8927
9513
  ...isLeftMinimizedStack ? { paddingLeft: minimizedStackLeftGutterPx } : {}
8928
9514
  },
8929
- children: /* @__PURE__ */ jsx10(
9515
+ children: /* @__PURE__ */ jsx11(
8930
9516
  "div",
8931
9517
  {
8932
9518
  className: "desktop-dock-popup__minimized-stack-track",
@@ -8945,7 +9531,7 @@ function WorkbenchHostDockPopup({
8945
9531
  capturedPreview,
8946
9532
  Boolean(capturePreview)
8947
9533
  );
8948
- return /* @__PURE__ */ jsx10(
9534
+ return /* @__PURE__ */ jsx11(
8949
9535
  WorkbenchHostDockPopupCard,
8950
9536
  {
8951
9537
  ref: registerCard(item.node.id),
@@ -8974,7 +9560,7 @@ function WorkbenchHostDockPopup({
8974
9560
  }
8975
9561
  )
8976
9562
  }
8977
- ) : /* @__PURE__ */ jsxs7("div", { className: "grid max-h-[min(52vh,420px)] grid-cols-[repeat(var(--desktop-dock-popup-columns,2),165px)] gap-2 overflow-auto overscroll-contain", children: [
9563
+ ) : /* @__PURE__ */ jsxs8("div", { className: "grid max-h-[min(52vh,420px)] grid-cols-[repeat(var(--desktop-dock-popup-columns,2),165px)] gap-2 overflow-auto overscroll-contain", children: [
8978
9564
  items.map((item) => {
8979
9565
  const previewMemoryKey = resolveDockPopupPreviewMemoryKey(
8980
9566
  item.node,
@@ -8986,7 +9572,7 @@ function WorkbenchHostDockPopup({
8986
9572
  capturedPreview,
8987
9573
  Boolean(capturePreview)
8988
9574
  );
8989
- return /* @__PURE__ */ jsx10(
9575
+ return /* @__PURE__ */ jsx11(
8990
9576
  WorkbenchHostDockPopupCard,
8991
9577
  {
8992
9578
  ref: registerCard(item.node.id),
@@ -9001,14 +9587,14 @@ function WorkbenchHostDockPopup({
9001
9587
  item.node.id
9002
9588
  );
9003
9589
  }),
9004
- showCreateNew !== false ? /* @__PURE__ */ jsxs7(
9590
+ showCreateNew !== false ? /* @__PURE__ */ jsxs8(
9005
9591
  "button",
9006
9592
  {
9007
9593
  className: "flex h-[103px] w-[165px] min-w-0 flex-col items-center justify-center gap-2 rounded-[8px] border border-dashed border-[var(--border-1)] bg-transparency-block text-center text-[var(--text-secondary)] transition-colors hover:bg-transparency-hover hover:text-[var(--text-primary)]",
9008
9594
  type: "button",
9009
9595
  onClick: onCreateNew,
9010
9596
  children: [
9011
- /* @__PURE__ */ jsx10(
9597
+ /* @__PURE__ */ jsx11(
9012
9598
  FileCreateIcon,
9013
9599
  {
9014
9600
  "aria-hidden": "true",
@@ -9016,7 +9602,7 @@ function WorkbenchHostDockPopup({
9016
9602
  size: 28
9017
9603
  }
9018
9604
  ),
9019
- /* @__PURE__ */ jsx10("span", { className: "text-xs font-semibold text-[var(--text-primary)]", children: newWindowLabel })
9605
+ /* @__PURE__ */ jsx11("span", { className: "text-xs font-semibold text-[var(--text-primary)]", children: newWindowLabel })
9020
9606
  ]
9021
9607
  }
9022
9608
  ) : null
@@ -9057,14 +9643,14 @@ function WorkbenchHostDockContextMenu({
9057
9643
  const hasOpenCommand = !hasOpenWindows;
9058
9644
  const hasDockActionGroup = Boolean(dockRetention) || hasNewWindowCommand || hasOpenCommand;
9059
9645
  const hasWindowActionGroup = hasOpenWindows;
9060
- return /* @__PURE__ */ jsxs7(
9646
+ return /* @__PURE__ */ jsxs8(
9061
9647
  "div",
9062
9648
  {
9063
9649
  className: "flex min-w-0 flex-col gap-1",
9064
9650
  "data-desktop-dock-context-menu": "true",
9065
9651
  role: "menu",
9066
9652
  children: [
9067
- hasOpenWindows ? /* @__PURE__ */ jsx10(Fragment5, { children: /* @__PURE__ */ jsx10("div", { className: "max-h-48 min-w-0 overflow-auto overscroll-contain", children: items.map((item) => /* @__PURE__ */ jsx10(
9653
+ hasOpenWindows ? /* @__PURE__ */ jsx11(Fragment5, { children: /* @__PURE__ */ jsx11("div", { className: "max-h-48 min-w-0 overflow-auto overscroll-contain", children: items.map((item) => /* @__PURE__ */ jsx11(
9068
9654
  WorkbenchHostDockContextMenuItem,
9069
9655
  {
9070
9656
  checked: !item.isMinimized,
@@ -9073,12 +9659,12 @@ function WorkbenchHostDockContextMenu({
9073
9659
  },
9074
9660
  item.node.id
9075
9661
  )) }) }) : null,
9076
- hasOpenWindows && (hasDockActionGroup || hasWindowActionGroup) ? /* @__PURE__ */ jsx10(WorkbenchHostDockContextMenuSeparator, {}) : null,
9077
- dockRetention ? /* @__PURE__ */ jsx10(
9662
+ hasOpenWindows && (hasDockActionGroup || hasWindowActionGroup) ? /* @__PURE__ */ jsx11(WorkbenchHostDockContextMenuSeparator, {}) : null,
9663
+ dockRetention ? /* @__PURE__ */ jsx11(
9078
9664
  WorkbenchHostDockContextMenuItem,
9079
9665
  {
9080
9666
  checked: dockRetention.checked,
9081
- checkedIcon: /* @__PURE__ */ jsx10(
9667
+ checkedIcon: /* @__PURE__ */ jsx11(
9082
9668
  PinFilledIcon,
9083
9669
  {
9084
9670
  "aria-hidden": "true",
@@ -9086,61 +9672,61 @@ function WorkbenchHostDockContextMenu({
9086
9672
  }
9087
9673
  ),
9088
9674
  disabled: dockRetention.disabled,
9089
- icon: /* @__PURE__ */ jsx10(PinIcon, { "aria-hidden": "true", className: "size-4" }),
9675
+ icon: /* @__PURE__ */ jsx11(PinIcon, { "aria-hidden": "true", className: "size-4" }),
9090
9676
  label: dockRetention.pendingLabel ?? dockRetention.label,
9091
9677
  onSelect: onRunDockRetentionAction
9092
9678
  }
9093
9679
  ) : null,
9094
- hasNewWindowCommand ? /* @__PURE__ */ jsx10(
9680
+ hasNewWindowCommand ? /* @__PURE__ */ jsx11(
9095
9681
  WorkbenchHostDockContextMenuItem,
9096
9682
  {
9097
- icon: /* @__PURE__ */ jsx10(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9683
+ icon: /* @__PURE__ */ jsx11(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9098
9684
  label: newWindowLabel,
9099
9685
  onSelect: onCreateNew
9100
9686
  }
9101
9687
  ) : null,
9102
- hasOpenCommand ? /* @__PURE__ */ jsx10(
9688
+ hasOpenCommand ? /* @__PURE__ */ jsx11(
9103
9689
  WorkbenchHostDockContextMenuItem,
9104
9690
  {
9105
9691
  disabled: !showOpen,
9106
- icon: /* @__PURE__ */ jsx10(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9692
+ icon: /* @__PURE__ */ jsx11(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9107
9693
  label: openLabel,
9108
9694
  onSelect: onCreateNew
9109
9695
  }
9110
9696
  ) : null,
9111
- hasOpenWindows ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
9112
- hasDockActionGroup ? /* @__PURE__ */ jsx10(WorkbenchHostDockContextMenuSeparator, {}) : null,
9113
- canShowAllWindows && onShowAllWindows ? /* @__PURE__ */ jsx10(
9697
+ hasOpenWindows ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
9698
+ hasDockActionGroup ? /* @__PURE__ */ jsx11(WorkbenchHostDockContextMenuSeparator, {}) : null,
9699
+ canShowAllWindows && onShowAllWindows ? /* @__PURE__ */ jsx11(
9114
9700
  WorkbenchHostDockContextMenuItem,
9115
9701
  {
9116
- icon: /* @__PURE__ */ jsx10(OverviewLayoutIcon, { "aria-hidden": "true", className: "size-4" }),
9702
+ icon: /* @__PURE__ */ jsx11(OverviewLayoutIcon, { "aria-hidden": "true", className: "size-4" }),
9117
9703
  label: showAllWindowsLabel,
9118
9704
  onSelect: onShowAllWindows
9119
9705
  }
9120
9706
  ) : null,
9121
- /* @__PURE__ */ jsx10(
9707
+ /* @__PURE__ */ jsx11(
9122
9708
  WorkbenchHostDockContextMenuItem,
9123
9709
  {
9124
9710
  disabled: !canEnterFullscreen || !onEnterFullscreen,
9125
- icon: /* @__PURE__ */ jsx10(MaximizeIcon, { "aria-hidden": "true", className: "size-4" }),
9711
+ icon: /* @__PURE__ */ jsx11(MaximizeIcon, { "aria-hidden": "true", className: "size-4" }),
9126
9712
  label: fullscreenLabel,
9127
9713
  onSelect: onEnterFullscreen
9128
9714
  }
9129
9715
  ),
9130
- /* @__PURE__ */ jsx10(
9716
+ /* @__PURE__ */ jsx11(
9131
9717
  WorkbenchHostDockContextMenuItem,
9132
9718
  {
9133
9719
  disabled: !onHide,
9134
- icon: /* @__PURE__ */ jsx10(MinimizeIcon, { "aria-hidden": "true", className: "size-4" }),
9720
+ icon: /* @__PURE__ */ jsx11(MinimizeIcon, { "aria-hidden": "true", className: "size-4" }),
9135
9721
  label: hideLabel,
9136
9722
  onSelect: onHide
9137
9723
  }
9138
9724
  ),
9139
- /* @__PURE__ */ jsx10(
9725
+ /* @__PURE__ */ jsx11(
9140
9726
  WorkbenchHostDockContextMenuItem,
9141
9727
  {
9142
9728
  disabled: !onQuit,
9143
- icon: /* @__PURE__ */ jsx10(CloseIcon, { "aria-hidden": "true", className: "size-4" }),
9729
+ icon: /* @__PURE__ */ jsx11(CloseIcon, { "aria-hidden": "true", className: "size-4" }),
9144
9730
  label: quitLabel,
9145
9731
  onSelect: onQuit
9146
9732
  }
@@ -9158,7 +9744,7 @@ function WorkbenchHostDockContextMenuItem({
9158
9744
  label,
9159
9745
  onSelect
9160
9746
  }) {
9161
- return /* @__PURE__ */ jsxs7(
9747
+ return /* @__PURE__ */ jsxs8(
9162
9748
  "button",
9163
9749
  {
9164
9750
  className: cn(
@@ -9175,20 +9761,20 @@ function WorkbenchHostDockContextMenuItem({
9175
9761
  onSelect();
9176
9762
  },
9177
9763
  children: [
9178
- /* @__PURE__ */ jsx10("span", { className: "flex size-4 shrink-0 items-center justify-center text-[var(--text-secondary)]", children: checked && checkedIcon ? checkedIcon : checked ? /* @__PURE__ */ jsx10(
9764
+ /* @__PURE__ */ jsx11("span", { className: "flex size-4 shrink-0 items-center justify-center text-[var(--text-secondary)]", children: checked && checkedIcon ? checkedIcon : checked ? /* @__PURE__ */ jsx11(
9179
9765
  CheckIcon,
9180
9766
  {
9181
9767
  "aria-hidden": "true",
9182
9768
  className: "size-4 text-[var(--tutti-purple)]"
9183
9769
  }
9184
9770
  ) : icon ?? null }),
9185
- /* @__PURE__ */ jsx10("span", { className: "min-w-0 truncate", children: label })
9771
+ /* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate", children: label })
9186
9772
  ]
9187
9773
  }
9188
9774
  );
9189
9775
  }
9190
9776
  function WorkbenchHostDockContextMenuSeparator() {
9191
- return /* @__PURE__ */ jsx10(
9777
+ return /* @__PURE__ */ jsx11(
9192
9778
  "div",
9193
9779
  {
9194
9780
  "aria-hidden": "true",
@@ -9304,7 +9890,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9304
9890
  const isMinimizedStack = variant === "minimized-stack";
9305
9891
  const [isLaunching, setIsLaunching] = useState7(false);
9306
9892
  const launchTimerRef = useRef7(null);
9307
- useEffect8(
9893
+ useEffect9(
9308
9894
  () => () => {
9309
9895
  if (launchTimerRef.current !== null) {
9310
9896
  clearTimeout(launchTimerRef.current);
@@ -9337,7 +9923,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9337
9923
  [handleSelect]
9338
9924
  );
9339
9925
  const hasReadyPreview = previewState.status === "ready";
9340
- return /* @__PURE__ */ jsxs7(
9926
+ return /* @__PURE__ */ jsxs8(
9341
9927
  "div",
9342
9928
  {
9343
9929
  ref,
@@ -9352,7 +9938,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9352
9938
  "data-minimized": item.isMinimized ? "true" : void 0,
9353
9939
  style,
9354
9940
  children: [
9355
- /* @__PURE__ */ jsxs7(
9941
+ /* @__PURE__ */ jsxs8(
9356
9942
  "div",
9357
9943
  {
9358
9944
  "aria-label": title,
@@ -9366,12 +9952,12 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9366
9952
  onClick: handleSelect,
9367
9953
  onKeyDown: handleSelectKeyDown,
9368
9954
  children: [
9369
- /* @__PURE__ */ jsx10(WorkbenchHostDockPopupCardPreview, { previewState }),
9370
- labelMode === "hover-overlay" && item.title?.trim() ? /* @__PURE__ */ jsx10(WorkbenchHostDockPopupCardLabel, { title: item.title }) : null
9955
+ /* @__PURE__ */ jsx11(WorkbenchHostDockPopupCardPreview, { previewState }),
9956
+ labelMode === "hover-overlay" && item.title?.trim() ? /* @__PURE__ */ jsx11(WorkbenchHostDockPopupCardLabel, { title: item.title }) : null
9371
9957
  ]
9372
9958
  }
9373
9959
  ),
9374
- /* @__PURE__ */ jsx10(
9960
+ /* @__PURE__ */ jsx11(
9375
9961
  Button2,
9376
9962
  {
9377
9963
  "aria-label": closeWindowLabel(title),
@@ -9385,10 +9971,10 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9385
9971
  event.stopPropagation();
9386
9972
  onCloseNode(item.node.id);
9387
9973
  },
9388
- children: /* @__PURE__ */ jsx10(CloseIcon, { className: "size-3.5" })
9974
+ children: /* @__PURE__ */ jsx11(CloseIcon, { className: "size-3.5" })
9389
9975
  }
9390
9976
  ),
9391
- item.isFocused ? /* @__PURE__ */ jsx10(
9977
+ item.isFocused ? /* @__PURE__ */ jsx11(
9392
9978
  "span",
9393
9979
  {
9394
9980
  "aria-hidden": "true",
@@ -9396,7 +9982,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9396
9982
  "data-desktop-dock-popup-card-active-overlay": "true"
9397
9983
  }
9398
9984
  ) : null,
9399
- isMinimizedStack ? /* @__PURE__ */ jsx10("span", { className: "desktop-dock-popup__fan-title-tip", title, children: title }) : null
9985
+ isMinimizedStack ? /* @__PURE__ */ jsx11("span", { className: "desktop-dock-popup__fan-title-tip", title, children: title }) : null
9400
9986
  ]
9401
9987
  }
9402
9988
  );
@@ -9405,23 +9991,23 @@ function WorkbenchHostDockPopupCardPreview({
9405
9991
  previewState
9406
9992
  }) {
9407
9993
  if (previewState.status !== "ready") {
9408
- return /* @__PURE__ */ jsxs7(
9994
+ return /* @__PURE__ */ jsxs8(
9409
9995
  "span",
9410
9996
  {
9411
9997
  className: "flex min-h-0 min-w-0 flex-1 flex-col justify-center gap-[7px] rounded-md border border-[var(--border-1)] bg-transparency-block px-3 py-[11px]",
9412
9998
  "aria-hidden": "true",
9413
9999
  "data-preview-state": previewState.status,
9414
10000
  children: [
9415
- /* @__PURE__ */ jsx10("span", { className: "block h-[7px] w-[72%] rounded-full bg-transparency-hover" }),
9416
- /* @__PURE__ */ jsx10("span", { className: "block h-[7px] w-[58%] rounded-full bg-transparency-hover" }),
9417
- /* @__PURE__ */ jsx10("span", { className: "block h-[7px] w-[34%] rounded-full bg-transparency-hover" })
10001
+ /* @__PURE__ */ jsx11("span", { className: "block h-[7px] w-[72%] rounded-full bg-transparency-hover" }),
10002
+ /* @__PURE__ */ jsx11("span", { className: "block h-[7px] w-[58%] rounded-full bg-transparency-hover" }),
10003
+ /* @__PURE__ */ jsx11("span", { className: "block h-[7px] w-[34%] rounded-full bg-transparency-hover" })
9418
10004
  ]
9419
10005
  }
9420
10006
  );
9421
10007
  }
9422
10008
  const preview = previewState.preview;
9423
10009
  if (preview.kind === "component") {
9424
- return /* @__PURE__ */ jsx10(
10010
+ return /* @__PURE__ */ jsx11(
9425
10011
  "span",
9426
10012
  {
9427
10013
  className: "block min-h-0 min-w-0 flex-1 overflow-hidden rounded-md",
@@ -9432,14 +10018,14 @@ function WorkbenchHostDockPopupCardPreview({
9432
10018
  }
9433
10019
  );
9434
10020
  }
9435
- return /* @__PURE__ */ jsx10(
10021
+ return /* @__PURE__ */ jsx11(
9436
10022
  "span",
9437
10023
  {
9438
10024
  className: "block min-h-0 min-w-0 flex-1 overflow-hidden rounded-md",
9439
10025
  "aria-hidden": "true",
9440
10026
  "data-preview-kind": preview.kind,
9441
10027
  "data-preview-state": previewState.status,
9442
- children: /* @__PURE__ */ jsx10(
10028
+ children: /* @__PURE__ */ jsx11(
9443
10029
  "img",
9444
10030
  {
9445
10031
  alt: "",
@@ -9452,7 +10038,7 @@ function WorkbenchHostDockPopupCardPreview({
9452
10038
  );
9453
10039
  }
9454
10040
  function WorkbenchHostDockPopupCardLabel({ title }) {
9455
- return /* @__PURE__ */ jsx10(
10041
+ return /* @__PURE__ */ jsx11(
9456
10042
  "span",
9457
10043
  {
9458
10044
  className: "pointer-events-none absolute inset-x-0 bottom-0 z-[1] flex h-[30px] items-end px-[10px] pb-0.5 text-[var(--white-stationary)] opacity-0 transition-opacity duration-150 [text-shadow:0_1px_2px_rgb(0_0_0_/_20%)] group-hover/dock-popup-card:opacity-100 group-focus-within/dock-popup-card:opacity-100",
@@ -9460,13 +10046,13 @@ function WorkbenchHostDockPopupCardLabel({ title }) {
9460
10046
  background: "linear-gradient(180deg, transparent 0%, color-mix(in srgb, hsl(var(--card)) 28%, transparent) 18%, color-mix(in srgb, hsl(var(--card)) 82%, transparent) 56%, color-mix(in srgb, hsl(var(--card)) 98%, transparent) 100%)"
9461
10047
  },
9462
10048
  title,
9463
- children: /* @__PURE__ */ jsx10("span", { className: "desktop-dock-popup__title-viewport block min-w-0 flex-1 overflow-hidden whitespace-nowrap", children: /* @__PURE__ */ jsx10("span", { className: "desktop-dock-popup__title-marquee inline-block max-w-full overflow-hidden text-[12px] font-semibold leading-5 text-ellipsis whitespace-nowrap", children: title }) })
10049
+ children: /* @__PURE__ */ jsx11("span", { className: "desktop-dock-popup__title-viewport block min-w-0 flex-1 overflow-hidden whitespace-nowrap", children: /* @__PURE__ */ jsx11("span", { className: "desktop-dock-popup__title-marquee inline-block max-w-full overflow-hidden text-[12px] font-semibold leading-5 text-ellipsis whitespace-nowrap", children: title }) })
9464
10050
  }
9465
10051
  );
9466
10052
  }
9467
10053
 
9468
10054
  // src/host/WorkbenchHostDock.tsx
9469
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
10055
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
9470
10056
  var minimizedDockPreviewViewport = {
9471
10057
  height: 34.2,
9472
10058
  width: 46.8
@@ -9511,7 +10097,7 @@ function WorkbenchHostDock({
9511
10097
  onMissionControlRequestOpen,
9512
10098
  workspaceId
9513
10099
  }) {
9514
- const minimizedNodeIDs = useMemo5(
10100
+ const minimizedNodeIDs = useMemo6(
9515
10101
  () => new Set(context.minimizedNodes.map((node) => node.id)),
9516
10102
  [context.minimizedNodes]
9517
10103
  );
@@ -9592,7 +10178,7 @@ function WorkbenchHostDock({
9592
10178
  labelTooltipOpenTimerRef.current = null;
9593
10179
  labelTooltipScheduledPointRef.current = null;
9594
10180
  }, []);
9595
- useEffect9(
10181
+ useEffect10(
9596
10182
  () => () => {
9597
10183
  clearHoverPanelCloseTimer();
9598
10184
  clearHoverPanelOpenTimer();
@@ -9686,7 +10272,7 @@ function WorkbenchHostDock({
9686
10272
  pendingDockStateRefreshRef.current = false;
9687
10273
  setDockStateRevision((revision) => revision + 1);
9688
10274
  }, []);
9689
- useEffect9(() => {
10275
+ useEffect10(() => {
9690
10276
  if (!dockStateSource) {
9691
10277
  return void 0;
9692
10278
  }
@@ -9698,14 +10284,14 @@ function WorkbenchHostDock({
9698
10284
  setDockStateRevision((revision) => revision + 1);
9699
10285
  });
9700
10286
  }, [dockStateSource]);
9701
- const renderedDockEntries = useMemo5(
10287
+ const renderedDockEntries = useMemo6(
9702
10288
  () => dockEntries.map((entry) => {
9703
10289
  const dynamicState = dockStateSource?.getEntryState(entry.id);
9704
10290
  return dynamicState ? { ...entry, ...dynamicState } : entry;
9705
10291
  }),
9706
10292
  [dockEntries, dockStateRevision, dockStateSource]
9707
10293
  );
9708
- const resolvedEntries = useMemo5(
10294
+ const resolvedEntries = useMemo6(
9709
10295
  () => resolveWorkbenchDockEntries({
9710
10296
  dockEntries: renderedDockEntries,
9711
10297
  minimizedNodeIds: minimizedNodeIDs,
@@ -9713,7 +10299,7 @@ function WorkbenchHostDock({
9713
10299
  }),
9714
10300
  [context.nodes, minimizedNodeIDs, renderedDockEntries]
9715
10301
  );
9716
- const minimizedDockSlots = useMemo5(
10302
+ const minimizedDockSlots = useMemo6(
9717
10303
  () => resolveWorkbenchMinimizedDockSlots({
9718
10304
  nodeDefinitions,
9719
10305
  nodes: context.minimizedNodes
@@ -9721,7 +10307,7 @@ function WorkbenchHostDock({
9721
10307
  [context.minimizedNodes, nodeDefinitions]
9722
10308
  );
9723
10309
  const { promotedNodeId, stackDispatching } = useMinimizedDockStackPromotion(minimizedDockSlots);
9724
- const dockItems = useMemo5(
10310
+ const dockItems = useMemo6(
9725
10311
  () => createWorkbenchHostDockItems({
9726
10312
  minimizedDockSlots,
9727
10313
  resolvedEntries
@@ -9732,7 +10318,7 @@ function WorkbenchHostDock({
9732
10318
  dockItems,
9733
10319
  (nodeId) => context.genie.shouldAnimateMinimizedDockEnter(nodeId)
9734
10320
  );
9735
- const presentDockItemKeys = useMemo5(
10321
+ const presentDockItemKeys = useMemo6(
9736
10322
  () => presentDockItems.map((item) => item.key).join("\n"),
9737
10323
  [presentDockItems]
9738
10324
  );
@@ -9741,7 +10327,7 @@ function WorkbenchHostDock({
9741
10327
  elementRefs: wallpaperToneElementRefs,
9742
10328
  itemKeys: presentDockItemKeys
9743
10329
  });
9744
- const dockWidth = useMemo5(
10330
+ const dockWidth = useMemo6(
9745
10331
  () => resolveWorkbenchHostDockItemsWidth(dockItems),
9746
10332
  [dockItems]
9747
10333
  );
@@ -9791,10 +10377,10 @@ function WorkbenchHostDock({
9791
10377
  }
9792
10378
  dockMeasureRef.current?.removeAttribute("data-dock-hover-panel-open");
9793
10379
  }, []);
9794
- useEffect9(() => {
10380
+ useEffect10(() => {
9795
10381
  activeHoverPanelRef.current = activeHoverPanel;
9796
10382
  }, [activeHoverPanel]);
9797
- useEffect9(() => {
10383
+ useEffect10(() => {
9798
10384
  activeLabelTooltipRef.current = activeLabelTooltip;
9799
10385
  }, [activeLabelTooltip]);
9800
10386
  const closeLabelTooltipImmediate = useCallback10(
@@ -10269,7 +10855,7 @@ function WorkbenchHostDock({
10269
10855
  })()
10270
10856
  )
10271
10857
  );
10272
- useEffect9(() => {
10858
+ useEffect10(() => {
10273
10859
  const shouldSubscribe = activePopup !== null || hasMinimizedPreviewCapture;
10274
10860
  if (!shouldSubscribe || !externalStateSource?.subscribe) {
10275
10861
  return void 0;
@@ -10278,7 +10864,7 @@ function WorkbenchHostDock({
10278
10864
  setExternalStateRevision((revision) => revision + 1);
10279
10865
  });
10280
10866
  }, [activePopup, externalStateSource, hasMinimizedPreviewCapture]);
10281
- useEffect9(() => {
10867
+ useEffect10(() => {
10282
10868
  const nextAttentionIds = /* @__PURE__ */ new Set();
10283
10869
  for (const entry of renderedDockEntries) {
10284
10870
  const nextToken = entry.attentionToken ?? null;
@@ -10319,7 +10905,7 @@ function WorkbenchHostDock({
10319
10905
  );
10320
10906
  }
10321
10907
  }, [renderedDockEntries]);
10322
- useEffect9(
10908
+ useEffect10(
10323
10909
  () => () => {
10324
10910
  for (const timeout of attentionTimeouts.current.values()) {
10325
10911
  globalThis.clearTimeout(timeout);
@@ -10501,20 +11087,20 @@ function WorkbenchHostDock({
10501
11087
  instanceMode: dockContextMenuInstanceMode,
10502
11088
  matchedNodes: popupEntry.matchedNodes
10503
11089
  }).kind === "launch";
10504
- return /* @__PURE__ */ jsxs8(
11090
+ return /* @__PURE__ */ jsxs9(
10505
11091
  "div",
10506
11092
  {
10507
11093
  className: "flex justify-center pointer-events-none",
10508
11094
  "data-dock-placement": dockPlacement,
10509
11095
  children: [
10510
- /* @__PURE__ */ jsx11(
11096
+ /* @__PURE__ */ jsx12(
10511
11097
  "div",
10512
11098
  {
10513
11099
  className: "desktop-dock-plate",
10514
11100
  style: dockFrameSize === null ? void 0 : {
10515
11101
  "--desktop-dock-frame-size": `${dockFrameSize}px`
10516
11102
  },
10517
- children: /* @__PURE__ */ jsxs8(
11103
+ children: /* @__PURE__ */ jsxs9(
10518
11104
  "div",
10519
11105
  {
10520
11106
  ref: dockMeasureRef,
@@ -10540,7 +11126,7 @@ function WorkbenchHostDock({
10540
11126
  role: "toolbar",
10541
11127
  style: dockPlacement === "left" ? { height: dockWidth } : { width: dockWidth },
10542
11128
  children: [
10543
- /* @__PURE__ */ jsx11(
11129
+ /* @__PURE__ */ jsx12(
10544
11130
  "span",
10545
11131
  {
10546
11132
  className: "desktop-dock__pointer-rail",
@@ -10548,7 +11134,7 @@ function WorkbenchHostDock({
10548
11134
  "aria-hidden": true
10549
11135
  }
10550
11136
  ),
10551
- /* @__PURE__ */ jsx11(
11137
+ /* @__PURE__ */ jsx12(
10552
11138
  "button",
10553
11139
  {
10554
11140
  "aria-label": i18n.t(
@@ -10559,12 +11145,12 @@ function WorkbenchHostDock({
10559
11145
  disabled: !dockScrollState.canScrollBackward,
10560
11146
  onClick: () => scrollDockItems("backward"),
10561
11147
  type: "button",
10562
- children: dockPlacement === "left" ? /* @__PURE__ */ jsx11(ChevronUpIcon, { size: 16 }) : /* @__PURE__ */ jsx11(ArrowLeftIcon, { size: 16 })
11148
+ children: dockPlacement === "left" ? /* @__PURE__ */ jsx12(ChevronUpIcon, { size: 16 }) : /* @__PURE__ */ jsx12(ArrowLeftIcon, { size: 16 })
10563
11149
  }
10564
11150
  ),
10565
- /* @__PURE__ */ jsx11("div", { ref: dockItemsRef, className: "desktop-dock__items", children: presentDockItems.map((dockItem) => {
11151
+ /* @__PURE__ */ jsx12("div", { ref: dockItemsRef, className: "desktop-dock__items", children: presentDockItems.map((dockItem) => {
10566
11152
  if (dockItem.item.kind === "separator") {
10567
- return /* @__PURE__ */ jsx11(
11153
+ return /* @__PURE__ */ jsx12(
10568
11154
  "span",
10569
11155
  {
10570
11156
  ref: registerWallpaperToneElement(dockItem.key),
@@ -10591,7 +11177,7 @@ function WorkbenchHostDock({
10591
11177
  });
10592
11178
  const hasHoverPanel = dockEntryHasHoverPanel(entry);
10593
11179
  const labelTooltipTarget2 = hasHoverPanel ? null : dockLabelTooltipTarget(`entry:${entry.id}`, entry.label);
10594
- const dockButton2 = /* @__PURE__ */ jsx11(
11180
+ const dockButton2 = /* @__PURE__ */ jsx12(
10595
11181
  "button",
10596
11182
  {
10597
11183
  "aria-expanded": currentPopup ? true : void 0,
@@ -10750,7 +11336,7 @@ function WorkbenchHostDock({
10750
11336
  entryId: entry.id
10751
11337
  });
10752
11338
  },
10753
- children: /* @__PURE__ */ jsxs8(
11339
+ children: /* @__PURE__ */ jsxs9(
10754
11340
  "span",
10755
11341
  {
10756
11342
  className: "desktop-dock__icon-shell",
@@ -10758,7 +11344,7 @@ function WorkbenchHostDock({
10758
11344
  "data-entry-state": entry.state?.kind ?? "enabled",
10759
11345
  "aria-hidden": true,
10760
11346
  children: [
10761
- /* @__PURE__ */ jsx11("span", { className: "desktop-dock__icon-content", children: entry.icon }),
11347
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__icon-content", children: entry.icon }),
10762
11348
  renderDockBadge(
10763
11349
  entry,
10764
11350
  resolvedEntry.matchedNodes.length
@@ -10768,7 +11354,7 @@ function WorkbenchHostDock({
10768
11354
  )
10769
11355
  }
10770
11356
  );
10771
- return /* @__PURE__ */ jsx11(
11357
+ return /* @__PURE__ */ jsx12(
10772
11358
  "span",
10773
11359
  {
10774
11360
  ref: registerDockSlot(anchorKey),
@@ -10869,7 +11455,7 @@ function WorkbenchHostDock({
10869
11455
  `minimized-stack:${slot.anchorKey}`,
10870
11456
  stackLabel
10871
11457
  );
10872
- const stackButton = /* @__PURE__ */ jsx11(
11458
+ const stackButton = /* @__PURE__ */ jsx12(
10873
11459
  "span",
10874
11460
  {
10875
11461
  "aria-expanded": stackPopupActive,
@@ -10903,7 +11489,7 @@ function WorkbenchHostDock({
10903
11489
  }
10904
11490
  );
10905
11491
  },
10906
- children: /* @__PURE__ */ jsxs8(
11492
+ children: /* @__PURE__ */ jsxs9(
10907
11493
  "span",
10908
11494
  {
10909
11495
  className: "desktop-dock__minimized-stack-icon",
@@ -10918,7 +11504,7 @@ function WorkbenchHostDock({
10918
11504
  (_, index) => {
10919
11505
  const node2 = slot.nodes[index];
10920
11506
  if (index === 0 && node2) {
10921
- return /* @__PURE__ */ jsx11(
11507
+ return /* @__PURE__ */ jsx12(
10922
11508
  WorkbenchHostDockMinimizedNodePreview,
10923
11509
  {
10924
11510
  capturePreview: captureMinimizedNodePreview,
@@ -10933,7 +11519,7 @@ function WorkbenchHostDock({
10933
11519
  minimizedDockPreviewFreezeKey(node2)
10934
11520
  );
10935
11521
  }
10936
- return /* @__PURE__ */ jsx11(
11522
+ return /* @__PURE__ */ jsx12(
10937
11523
  "span",
10938
11524
  {
10939
11525
  "aria-hidden": "true",
@@ -10943,13 +11529,13 @@ function WorkbenchHostDock({
10943
11529
  );
10944
11530
  }
10945
11531
  ),
10946
- /* @__PURE__ */ jsx11("span", { className: "desktop-dock__count-badge", children: slot.nodes.length })
11532
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__count-badge", children: slot.nodes.length })
10947
11533
  ]
10948
11534
  }
10949
11535
  )
10950
11536
  }
10951
11537
  );
10952
- return /* @__PURE__ */ jsx11(
11538
+ return /* @__PURE__ */ jsx12(
10953
11539
  "span",
10954
11540
  {
10955
11541
  ref: registerDockSlot(slot.anchorKey),
@@ -11004,7 +11590,7 @@ function WorkbenchHostDock({
11004
11590
  `minimized-node:${node.id}`,
11005
11591
  node.title
11006
11592
  );
11007
- const dockButton = /* @__PURE__ */ jsx11(
11593
+ const dockButton = /* @__PURE__ */ jsx12(
11008
11594
  "span",
11009
11595
  {
11010
11596
  "aria-label": i18n.t("launch", { title: node.title }),
@@ -11065,7 +11651,7 @@ function WorkbenchHostDock({
11065
11651
  }
11066
11652
  );
11067
11653
  },
11068
- children: /* @__PURE__ */ jsx11(
11654
+ children: /* @__PURE__ */ jsx12(
11069
11655
  WorkbenchHostDockMinimizedNodePreview,
11070
11656
  {
11071
11657
  capturePreview: isPendingMinimizedNode ? void 0 : captureMinimizedNodePreview,
@@ -11079,7 +11665,7 @@ function WorkbenchHostDock({
11079
11665
  )
11080
11666
  }
11081
11667
  );
11082
- return /* @__PURE__ */ jsx11(
11668
+ return /* @__PURE__ */ jsx12(
11083
11669
  "span",
11084
11670
  {
11085
11671
  ref: registerDockSlot(slot.anchorKey),
@@ -11129,7 +11715,7 @@ function WorkbenchHostDock({
11129
11715
  dockItem.key
11130
11716
  );
11131
11717
  }) }),
11132
- /* @__PURE__ */ jsx11(
11718
+ /* @__PURE__ */ jsx12(
11133
11719
  "button",
11134
11720
  {
11135
11721
  "aria-label": i18n.t(
@@ -11140,10 +11726,10 @@ function WorkbenchHostDock({
11140
11726
  disabled: !dockScrollState.canScrollForward,
11141
11727
  onClick: () => scrollDockItems("forward"),
11142
11728
  type: "button",
11143
- children: dockPlacement === "left" ? /* @__PURE__ */ jsx11(ChevronDownIcon, { size: 16 }) : /* @__PURE__ */ jsx11(ArrowRightIcon, { size: 16 })
11729
+ children: dockPlacement === "left" ? /* @__PURE__ */ jsx12(ChevronDownIcon, { size: 16 }) : /* @__PURE__ */ jsx12(ArrowRightIcon, { size: 16 })
11144
11730
  }
11145
11731
  ),
11146
- activeHoverPanel ? /* @__PURE__ */ jsx11(
11732
+ activeHoverPanel ? /* @__PURE__ */ jsx12(
11147
11733
  WorkbenchHostDockHoverPanel,
11148
11734
  {
11149
11735
  entry: resolvedEntries.find(
@@ -11176,7 +11762,7 @@ function WorkbenchHostDock({
11176
11762
  }
11177
11763
  }
11178
11764
  ) : null,
11179
- activeLabelTooltip ? /* @__PURE__ */ jsx11(
11765
+ activeLabelTooltip ? /* @__PURE__ */ jsx12(
11180
11766
  WorkbenchHostDockLabelTooltip,
11181
11767
  {
11182
11768
  placement: dockPlacement,
@@ -11188,7 +11774,7 @@ function WorkbenchHostDock({
11188
11774
  )
11189
11775
  }
11190
11776
  ),
11191
- popupEntry && activePopup ? /* @__PURE__ */ jsx11(
11777
+ popupEntry && activePopup ? /* @__PURE__ */ jsx12(
11192
11778
  WorkbenchHostDockPopup,
11193
11779
  {
11194
11780
  anchorRect: activePopup.anchorRect,
@@ -11375,7 +11961,7 @@ function WorkbenchHostDock({
11375
11961
  variant: activePopup.kind === "context-menu" ? "context-menu" : "default"
11376
11962
  }
11377
11963
  ) : null,
11378
- activeMinimizedStackSlot && activeMinimizedStackPopup ? /* @__PURE__ */ jsx11(
11964
+ activeMinimizedStackSlot && activeMinimizedStackPopup ? /* @__PURE__ */ jsx12(
11379
11965
  WorkbenchHostDockPopup,
11380
11966
  {
11381
11967
  anchorRect: activeMinimizedStackPopup,
@@ -11479,7 +12065,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11479
12065
  const [previewImageUrl, setPreviewImageUrl] = useState8(
11480
12066
  () => deferPreview || providePreview ? null : readCachedWorkbenchNodePreviewImage(node.id)
11481
12067
  );
11482
- useEffect9(() => {
12068
+ useEffect10(() => {
11483
12069
  if (deferPreview || !providePreview || componentPreview !== void 0) {
11484
12070
  return void 0;
11485
12071
  }
@@ -11528,7 +12114,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11528
12114
  node.minimizedAtUnixMs,
11529
12115
  providePreview
11530
12116
  ]);
11531
- useEffect9(() => {
12117
+ useEffect10(() => {
11532
12118
  if (deferPreview || providePreview) {
11533
12119
  return void 0;
11534
12120
  }
@@ -11590,7 +12176,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11590
12176
  return renderMinimizedDockPreviewContent(componentPreview, className);
11591
12177
  }
11592
12178
  if (previewImageUrl) {
11593
- return /* @__PURE__ */ jsx11(
12179
+ return /* @__PURE__ */ jsx12(
11594
12180
  "span",
11595
12181
  {
11596
12182
  className: [
@@ -11599,7 +12185,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11599
12185
  className
11600
12186
  ].filter(Boolean).join(" "),
11601
12187
  "aria-hidden": "true",
11602
- children: /* @__PURE__ */ jsx11(
12188
+ children: /* @__PURE__ */ jsx12(
11603
12189
  "img",
11604
12190
  {
11605
12191
  alt: "",
@@ -11614,22 +12200,22 @@ function WorkbenchHostDockMinimizedNodePreview({
11614
12200
  return renderMinimizedDockPreviewPlaceholder(className);
11615
12201
  }
11616
12202
  function renderMinimizedDockPreviewPlaceholder(className) {
11617
- return /* @__PURE__ */ jsxs8(
12203
+ return /* @__PURE__ */ jsxs9(
11618
12204
  "span",
11619
12205
  {
11620
12206
  className: ["desktop-dock__minimized-preview", className].filter(Boolean).join(" "),
11621
12207
  "aria-hidden": "true",
11622
12208
  children: [
11623
- /* @__PURE__ */ jsx11("span", { className: "desktop-dock__minimized-preview-line" }),
11624
- /* @__PURE__ */ jsx11("span", { className: "desktop-dock__minimized-preview-line desktop-dock__minimized-preview-line--short" }),
11625
- /* @__PURE__ */ jsx11("span", { className: "desktop-dock__minimized-preview-line desktop-dock__minimized-preview-line--accent" })
12209
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__minimized-preview-line" }),
12210
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__minimized-preview-line desktop-dock__minimized-preview-line--short" }),
12211
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__minimized-preview-line desktop-dock__minimized-preview-line--accent" })
11626
12212
  ]
11627
12213
  }
11628
12214
  );
11629
12215
  }
11630
12216
  function renderMinimizedDockPreviewContent(preview, className) {
11631
12217
  if (preview.kind === "image") {
11632
- return /* @__PURE__ */ jsx11(
12218
+ return /* @__PURE__ */ jsx12(
11633
12219
  "span",
11634
12220
  {
11635
12221
  className: [
@@ -11638,7 +12224,7 @@ function renderMinimizedDockPreviewContent(preview, className) {
11638
12224
  className
11639
12225
  ].filter(Boolean).join(" "),
11640
12226
  "aria-hidden": "true",
11641
- children: /* @__PURE__ */ jsx11(
12227
+ children: /* @__PURE__ */ jsx12(
11642
12228
  "img",
11643
12229
  {
11644
12230
  alt: "",
@@ -11650,7 +12236,7 @@ function renderMinimizedDockPreviewContent(preview, className) {
11650
12236
  }
11651
12237
  );
11652
12238
  }
11653
- return /* @__PURE__ */ jsx11(
12239
+ return /* @__PURE__ */ jsx12(
11654
12240
  WorkbenchHostDockFrozenComponentPreview,
11655
12241
  {
11656
12242
  className,
@@ -11670,7 +12256,7 @@ function WorkbenchHostDockFrozenComponentPreview({
11670
12256
  }
11671
12257
  setFrozenMarkup(sourceRef.current?.innerHTML ?? "");
11672
12258
  }, [frozenMarkup]);
11673
- return /* @__PURE__ */ jsx11(
12259
+ return /* @__PURE__ */ jsx12(
11674
12260
  "span",
11675
12261
  {
11676
12262
  className: [
@@ -11679,14 +12265,14 @@ function WorkbenchHostDockFrozenComponentPreview({
11679
12265
  className
11680
12266
  ].filter(Boolean).join(" "),
11681
12267
  "aria-hidden": "true",
11682
- children: frozenMarkup === null ? /* @__PURE__ */ jsx11(
12268
+ children: frozenMarkup === null ? /* @__PURE__ */ jsx12(
11683
12269
  "span",
11684
12270
  {
11685
12271
  ref: sourceRef,
11686
12272
  className: "desktop-dock__minimized-preview-freeze-source",
11687
12273
  children: preview.element
11688
12274
  }
11689
- ) : /* @__PURE__ */ jsx11(
12275
+ ) : /* @__PURE__ */ jsx12(
11690
12276
  "span",
11691
12277
  {
11692
12278
  className: "desktop-dock__minimized-preview-frozen-content",
@@ -11754,18 +12340,18 @@ function renderDockBadge(entry, matchedNodeCount) {
11754
12340
  return null;
11755
12341
  }
11756
12342
  if (badge.kind === "count") {
11757
- return /* @__PURE__ */ jsx11("span", { className: "desktop-dock__count-badge", children: badge.value });
12343
+ return /* @__PURE__ */ jsx12("span", { className: "desktop-dock__count-badge", children: badge.value });
11758
12344
  }
11759
12345
  if (badge.kind === "custom") {
11760
- return /* @__PURE__ */ jsx11("span", { className: "desktop-dock__custom-badge", children: badge.content });
12346
+ return /* @__PURE__ */ jsx12("span", { className: "desktop-dock__custom-badge", children: badge.content });
11761
12347
  }
11762
- return /* @__PURE__ */ jsx11("span", { className: "desktop-dock__status-badge", "data-status": badge.status });
12348
+ return /* @__PURE__ */ jsx12("span", { className: "desktop-dock__status-badge", "data-status": badge.status });
11763
12349
  }
11764
12350
  function WorkbenchHostDockLabelTooltip({
11765
12351
  placement,
11766
12352
  state
11767
12353
  }) {
11768
- return /* @__PURE__ */ jsx11(
12354
+ return /* @__PURE__ */ jsx12(
11769
12355
  "div",
11770
12356
  {
11771
12357
  className: "desktop-dock__label-tooltip",
@@ -11829,7 +12415,7 @@ function WorkbenchHostDockHoverPanel({
11829
12415
  }
11830
12416
  })();
11831
12417
  };
11832
- return /* @__PURE__ */ jsxs8(
12418
+ return /* @__PURE__ */ jsxs9(
11833
12419
  "div",
11834
12420
  {
11835
12421
  ref: hoverPanelRef,
@@ -11848,13 +12434,13 @@ function WorkbenchHostDockHoverPanel({
11848
12434
  "--desktop-dock-hover-panel-anchor-width": `${state.anchorRect.width}px`
11849
12435
  },
11850
12436
  children: [
11851
- /* @__PURE__ */ jsx11("div", { className: "desktop-dock__hover-panel-title", children: entry.label }),
11852
- entry.state?.reason ? /* @__PURE__ */ jsx11("div", { className: "desktop-dock__hover-panel-description", children: stripDockDescriptionTerminalPunctuation(entry.state.reason) }) : null,
11853
- entry.hoverActions?.length ? /* @__PURE__ */ jsx11("div", { className: "desktop-dock__hover-actions", children: entry.hoverActions.map((action) => {
12437
+ /* @__PURE__ */ jsx12("div", { className: "desktop-dock__hover-panel-title", children: entry.label }),
12438
+ entry.state?.reason ? /* @__PURE__ */ jsx12("div", { className: "desktop-dock__hover-panel-description", children: stripDockDescriptionTerminalPunctuation(entry.state.reason) }) : null,
12439
+ entry.hoverActions?.length ? /* @__PURE__ */ jsx12("div", { className: "desktop-dock__hover-actions", children: entry.hoverActions.map((action) => {
11854
12440
  const actionKey = dockActionKey(entry.id, action.id);
11855
12441
  const isLocallyPending = pendingActionKeys.has(actionKey);
11856
12442
  const isPending = isLocallyPending || action.disabled === true && action.pendingLabel !== void 0;
11857
- return /* @__PURE__ */ jsx11(
12443
+ return /* @__PURE__ */ jsx12(
11858
12444
  Button3,
11859
12445
  {
11860
12446
  "aria-busy": isPending ? true : void 0,
@@ -12095,7 +12681,7 @@ function useDockPresenceItems(items, shouldAnimateMinimizedDockEnter) {
12095
12681
  }))
12096
12682
  );
12097
12683
  const initialized = useRef8(false);
12098
- useEffect9(() => {
12684
+ useEffect10(() => {
12099
12685
  let nextSettleMs = dockPresenceAnimationMs;
12100
12686
  setPresentItems((current) => {
12101
12687
  const filteredItems = resolveDockPresenceItems({
@@ -12397,7 +12983,7 @@ function useDockBounce(slotRefs) {
12397
12983
  },
12398
12984
  [slotRefs]
12399
12985
  );
12400
- useEffect9(
12986
+ useEffect10(
12401
12987
  () => () => {
12402
12988
  for (const anchorKey of timeoutsRef.current.keys()) {
12403
12989
  clearDockBounce(anchorKey);
@@ -12570,7 +13156,7 @@ function createWorkbenchHostNodeHeaderContext({
12570
13156
  }
12571
13157
 
12572
13158
  // src/host/WorkbenchHostWindowActions.tsx
12573
- import { jsx as jsx12 } from "react/jsx-runtime";
13159
+ import { jsx as jsx13 } from "react/jsx-runtime";
12574
13160
  function WorkbenchHostWindowActions({
12575
13161
  context,
12576
13162
  host,
@@ -12583,7 +13169,7 @@ function WorkbenchHostWindowActions({
12583
13169
  }
12584
13170
  const minimizable = definition.window?.minimizable !== false;
12585
13171
  const closable = definition.window?.closable !== false;
12586
- return /* @__PURE__ */ jsx12(
13172
+ return /* @__PURE__ */ jsx13(
12587
13173
  WorkbenchWindowTrafficLights,
12588
13174
  {
12589
13175
  close: closable ? {
@@ -12606,11 +13192,11 @@ function WorkbenchHostWindowActions({
12606
13192
  }
12607
13193
 
12608
13194
  // src/host/useWorkbenchHostSurfaceRenderers.tsx
12609
- import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
13195
+ import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
12610
13196
  function useWorkbenchHostSurfaceRenderers(input) {
12611
- const renderBottomChrome = useMemo6(() => {
13197
+ const renderBottomChrome = useMemo7(() => {
12612
13198
  const renderChrome = input.renderBottomChrome;
12613
- return renderChrome ? () => /* @__PURE__ */ jsx13(
13199
+ return renderChrome ? () => /* @__PURE__ */ jsx14(
12614
13200
  WorkbenchHostSurfaceRenderErrorBoundary,
12615
13201
  {
12616
13202
  debugDiagnostics: input.debugDiagnostics,
@@ -12621,7 +13207,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12621
13207
  fallbackKind: "bottom-chrome",
12622
13208
  resetKey: `${input.workspaceId}:bottom-chrome`,
12623
13209
  workspaceId: input.workspaceId,
12624
- children: /* @__PURE__ */ jsx13(
13210
+ children: /* @__PURE__ */ jsx14(
12625
13211
  WorkbenchHostChromeRenderer,
12626
13212
  {
12627
13213
  context: input.chromeContext,
@@ -12636,9 +13222,9 @@ function useWorkbenchHostSurfaceRenderers(input) {
12636
13222
  input.renderBottomChrome,
12637
13223
  input.workspaceId
12638
13224
  ]);
12639
- const renderTopChrome = useMemo6(() => {
13225
+ const renderTopChrome = useMemo7(() => {
12640
13226
  const renderChrome = input.renderTopChrome;
12641
- return renderChrome ? () => /* @__PURE__ */ jsx13(
13227
+ return renderChrome ? () => /* @__PURE__ */ jsx14(
12642
13228
  WorkbenchHostSurfaceRenderErrorBoundary,
12643
13229
  {
12644
13230
  debugDiagnostics: input.debugDiagnostics,
@@ -12649,7 +13235,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12649
13235
  fallbackKind: "top-chrome",
12650
13236
  resetKey: `${input.workspaceId}:top-chrome`,
12651
13237
  workspaceId: input.workspaceId,
12652
- children: /* @__PURE__ */ jsx13(
13238
+ children: /* @__PURE__ */ jsx14(
12653
13239
  WorkbenchHostChromeRenderer,
12654
13240
  {
12655
13241
  context: input.chromeContext,
@@ -12698,7 +13284,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12698
13284
  ]
12699
13285
  );
12700
13286
  const renderDock = useCallback11(
12701
- (context) => /* @__PURE__ */ jsx13(
13287
+ (context) => /* @__PURE__ */ jsx14(
12702
13288
  WorkbenchHostSurfaceRenderErrorBoundary,
12703
13289
  {
12704
13290
  debugDiagnostics: input.debugDiagnostics,
@@ -12710,7 +13296,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12710
13296
  fallbackKind: "dock",
12711
13297
  resetKey: `${input.workspaceId}:dock`,
12712
13298
  workspaceId: input.workspaceId,
12713
- children: /* @__PURE__ */ jsx13(
13299
+ children: /* @__PURE__ */ jsx14(
12714
13300
  WorkbenchHostDock,
12715
13301
  {
12716
13302
  captureNodePreviewImage,
@@ -12764,7 +13350,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12764
13350
  host: input.hostSession,
12765
13351
  workspaceId: input.workspaceId
12766
13352
  });
12767
- return /* @__PURE__ */ jsx13(
13353
+ return /* @__PURE__ */ jsx14(
12768
13354
  WorkbenchHostNodeRenderErrorBoundary,
12769
13355
  {
12770
13356
  debugDiagnostics: input.debugDiagnostics,
@@ -12775,7 +13361,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12775
13361
  }),
12776
13362
  resetKey: `${context.node.id}:${context.node.data.typeId}:${input.externalStateRevision}`,
12777
13363
  workspaceId: input.workspaceId,
12778
- children: /* @__PURE__ */ jsx13(
13364
+ children: /* @__PURE__ */ jsx14(
12779
13365
  WorkbenchHostNodeBodyRenderer,
12780
13366
  {
12781
13367
  context: bodyContext,
@@ -12795,7 +13381,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12795
13381
  ]
12796
13382
  );
12797
13383
  const renderWindowActions = useCallback11(
12798
- (context) => /* @__PURE__ */ jsx13(
13384
+ (context) => /* @__PURE__ */ jsx14(
12799
13385
  WorkbenchHostWindowActions,
12800
13386
  {
12801
13387
  context,
@@ -12988,7 +13574,7 @@ var WorkbenchHostSurfaceRenderErrorBoundary = class extends Component {
12988
13574
  }
12989
13575
  render() {
12990
13576
  if (this.state.hasError) {
12991
- return /* @__PURE__ */ jsx13(
13577
+ return /* @__PURE__ */ jsx14(
12992
13578
  "div",
12993
13579
  {
12994
13580
  "data-workbench-surface-render-error": this.props.fallbackKind,
@@ -13047,7 +13633,7 @@ var WorkbenchHostNodeRenderErrorBoundary = class extends Component {
13047
13633
  }
13048
13634
  render() {
13049
13635
  if (this.state.hasError) {
13050
- return /* @__PURE__ */ jsxs9(
13636
+ return /* @__PURE__ */ jsxs10(
13051
13637
  "div",
13052
13638
  {
13053
13639
  "data-workbench-node-render-error": "true",
@@ -13065,7 +13651,7 @@ var WorkbenchHostNodeRenderErrorBoundary = class extends Component {
13065
13651
  width: "100%"
13066
13652
  },
13067
13653
  children: [
13068
- /* @__PURE__ */ jsx13(
13654
+ /* @__PURE__ */ jsx14(
13069
13655
  "div",
13070
13656
  {
13071
13657
  "data-workbench-node-render-error-message": "true",
@@ -13077,8 +13663,8 @@ var WorkbenchHostNodeRenderErrorBoundary = class extends Component {
13077
13663
  children: "This workspace view failed to render."
13078
13664
  }
13079
13665
  ),
13080
- /* @__PURE__ */ jsx13("div", { style: { fontSize: 12 }, children: "Try selecting another conversation or reopen the window." }),
13081
- /* @__PURE__ */ jsx13(
13666
+ /* @__PURE__ */ jsx14("div", { style: { fontSize: 12 }, children: "Try selecting another conversation or reopen the window." }),
13667
+ /* @__PURE__ */ jsx14(
13082
13668
  "button",
13083
13669
  {
13084
13670
  type: "button",
@@ -13121,7 +13707,7 @@ function WorkbenchHostChromeRenderer({
13121
13707
  }
13122
13708
 
13123
13709
  // src/host/WorkbenchHost.tsx
13124
- import { jsx as jsx14 } from "react/jsx-runtime";
13710
+ import { jsx as jsx15 } from "react/jsx-runtime";
13125
13711
  var noop3 = () => {
13126
13712
  };
13127
13713
  function WorkbenchHost({
@@ -13155,7 +13741,7 @@ function WorkbenchHost({
13155
13741
  windowManagement,
13156
13742
  workspaceId
13157
13743
  }) {
13158
- const hostRuntimeConfig = useMemo7(
13744
+ const hostRuntimeConfig = useMemo8(
13159
13745
  () => resolveWorkbenchHostRuntimeConfig({
13160
13746
  contributions,
13161
13747
  externalStateSource,
@@ -13171,7 +13757,7 @@ function WorkbenchHost({
13171
13757
  onNodeCloseRequest
13172
13758
  ]
13173
13759
  );
13174
- const hostDockEntries = useMemo7(
13760
+ const hostDockEntries = useMemo8(
13175
13761
  () => resolveWorkbenchHostDockEntries({
13176
13762
  contributions,
13177
13763
  dockEntries
@@ -13234,7 +13820,7 @@ function WorkbenchHost({
13234
13820
  });
13235
13821
  const missionControlPresence = useWorkbenchMissionControlPresence(missionControlState);
13236
13822
  const missionControlRenderedState = missionControlPresence.state;
13237
- return /* @__PURE__ */ jsx14(
13823
+ return /* @__PURE__ */ jsx15(
13238
13824
  WorkbenchSurface,
13239
13825
  {
13240
13826
  className,
@@ -13248,7 +13834,7 @@ function WorkbenchHost({
13248
13834
  missionControlPhase: missionControlPresence.phase,
13249
13835
  minimizeAnimation,
13250
13836
  presentation: missionControlState?.presentation ?? null,
13251
- renderBackdrop: missionControlRenderedState ? () => /* @__PURE__ */ jsx14(
13837
+ renderBackdrop: missionControlRenderedState ? () => /* @__PURE__ */ jsx15(
13252
13838
  WorkbenchMissionControlBackdrop,
13253
13839
  {
13254
13840
  onExitTransitionComplete: () => missionControlPresence.completeExitTransition(),
@@ -13259,7 +13845,7 @@ function WorkbenchHost({
13259
13845
  renderDock: surfaceRenderers.renderDock,
13260
13846
  renderNode: surfaceRenderers.renderNode,
13261
13847
  renderNodeGeniePreview: surfaceRenderers.renderNodeGeniePreview,
13262
- renderOverlay: missionControlRenderedState ? () => /* @__PURE__ */ jsx14(
13848
+ renderOverlay: missionControlRenderedState ? () => /* @__PURE__ */ jsx15(
13263
13849
  WorkbenchMissionControlOverlay,
13264
13850
  {
13265
13851
  i18n: missionControlI18n,