@tutti-os/workbench-surface 0.0.75 → 0.0.77

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;
974
1102
  }
975
- return { ...state, nodes, nodeStack };
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;
1148
+ }
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";
@@ -1325,6 +1835,9 @@ function useWorkbenchMissionControlPresence(state) {
1325
1835
  const enterFrameRef = useRef2(null);
1326
1836
  const setPresencePhase = useCallback(
1327
1837
  (nextPhase) => {
1838
+ if (phaseRef.current === nextPhase) {
1839
+ return;
1840
+ }
1328
1841
  phaseRef.current = nextPhase;
1329
1842
  setPhase(nextPhase);
1330
1843
  },
@@ -1373,7 +1886,7 @@ function useWorkbenchMissionControlPresence(state) {
1373
1886
  }
1374
1887
 
1375
1888
  // src/mission-control/useWorkbenchMissionControlState.ts
1376
- import { useCallback as useCallback2, useEffect, useMemo, useState as useState3 } from "react";
1889
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState3 } from "react";
1377
1890
  import {
1378
1891
  useExternalStoreSnapshot
1379
1892
  } from "@tutti-os/ui-react-hooks";
@@ -1560,13 +2073,13 @@ function useWorkbenchMissionControlState({
1560
2073
  return nextVisibleNodes.filter((node) => scopedNodeIdSet.has(node.id));
1561
2074
  }, [scopedNodeIdSet, snapshot?.visibleNodes]);
1562
2075
  const [selectedNodeIds, setSelectedNodeIds] = useState3([]);
1563
- useEffect(() => {
2076
+ useEffect2(() => {
1564
2077
  if (mode === null) {
1565
2078
  return;
1566
2079
  }
1567
2080
  setSelectedNodeIds([]);
1568
2081
  }, [mode]);
1569
- useEffect(() => {
2082
+ useEffect2(() => {
1570
2083
  if (mode !== null && visibleNodes.length === 0) {
1571
2084
  onRequestClose();
1572
2085
  }
@@ -1637,13 +2150,13 @@ function useWorkbenchMissionControlState({
1637
2150
  [adapter, onRequestClose]
1638
2151
  );
1639
2152
  const applyLayoutAndClose = useCallback2(
1640
- (nodeIds2, nextPreset) => {
2153
+ (nodeIds2, nextPreset, lock) => {
1641
2154
  if (!adapter || nodeIds2.length < 2) {
1642
2155
  return;
1643
2156
  }
1644
2157
  onRequestClose();
1645
2158
  window.requestAnimationFrame(() => {
1646
- adapter.applyLayoutPreset(nodeIds2, nextPreset);
2159
+ adapter.applyLayoutPreset(nodeIds2, nextPreset, lock);
1647
2160
  });
1648
2161
  },
1649
2162
  [adapter, onRequestClose]
@@ -1668,11 +2181,15 @@ function useWorkbenchMissionControlState({
1668
2181
  [selectedNodeIds]
1669
2182
  );
1670
2183
  const applyPreset = useCallback2(
1671
- (nextPreset) => {
2184
+ (nextPreset, options) => {
1672
2185
  if (!canApplyPreset(nextPreset)) {
1673
2186
  return;
1674
2187
  }
1675
- applyLayoutAndClose(orderedSelectedNodeIds, nextPreset);
2188
+ applyLayoutAndClose(
2189
+ orderedSelectedNodeIds,
2190
+ nextPreset,
2191
+ options?.lock ?? false
2192
+ );
1676
2193
  },
1677
2194
  [applyLayoutAndClose, canApplyPreset, orderedSelectedNodeIds]
1678
2195
  );
@@ -1699,7 +2216,7 @@ function useWorkbenchMissionControlState({
1699
2216
  selectedNodeIdSet
1700
2217
  ]
1701
2218
  );
1702
- useEffect(() => {
2219
+ useEffect2(() => {
1703
2220
  if (mode === null) {
1704
2221
  return void 0;
1705
2222
  }
@@ -1714,23 +2231,30 @@ function useWorkbenchMissionControlState({
1714
2231
  window.removeEventListener("keydown", onKeyDown, true);
1715
2232
  };
1716
2233
  }, [mode, onRequestClose]);
1717
- if (mode === null || presentation === null) {
1718
- return null;
1719
- }
1720
- return {
1721
- applyPreset,
1722
- canApplyPreset,
1723
- canUsePreset,
1724
- mode,
1725
- presentation,
1726
- selectedCount: orderedSelectedNodeIds.length
1727
- };
2234
+ return useMemo(
2235
+ () => mode === null || presentation === null ? null : {
2236
+ applyPreset,
2237
+ canApplyPreset,
2238
+ canUsePreset,
2239
+ mode,
2240
+ presentation,
2241
+ selectedCount: orderedSelectedNodeIds.length
2242
+ },
2243
+ [
2244
+ applyPreset,
2245
+ canApplyPreset,
2246
+ canUsePreset,
2247
+ mode,
2248
+ orderedSelectedNodeIds.length,
2249
+ presentation
2250
+ ]
2251
+ );
1728
2252
  }
1729
2253
 
1730
2254
  // src/react/WorkbenchSurface.tsx
1731
2255
  import {
1732
2256
  useCallback as useCallback7,
1733
- useEffect as useEffect4
2257
+ useEffect as useEffect5
1734
2258
  } from "react";
1735
2259
 
1736
2260
  // src/react/WorkbenchDockFrame.tsx
@@ -1832,7 +2356,7 @@ function useWorkbenchSelector(selector) {
1832
2356
  }
1833
2357
 
1834
2358
  // src/react/WorkbenchDockFrame.tsx
1835
- import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
2359
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1836
2360
  function WorkbenchDockFrame({
1837
2361
  dockPlacement = "bottom",
1838
2362
  genie,
@@ -1869,7 +2393,7 @@ function WorkbenchDockFrame({
1869
2393
  if (!renderDock && minimizedNodes.length === 0) {
1870
2394
  return null;
1871
2395
  }
1872
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2396
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
1873
2397
  hasFullscreenNode ? /* @__PURE__ */ jsx3(
1874
2398
  "div",
1875
2399
  {
@@ -1926,8 +2450,44 @@ function mergePendingMinimizedDockNode(nodes, pendingNode) {
1926
2450
  return [...nodes.filter((node) => node.id !== pendingNode.id), pendingNode];
1927
2451
  }
1928
2452
 
2453
+ // src/react/WorkbenchLockedSlotLayer.tsx
2454
+ import { useMemo as useMemo3 } from "react";
2455
+ import { jsx as jsx4 } from "react/jsx-runtime";
2456
+ var selectLockedLayout = (state) => state.lockedLayout;
2457
+ var selectSurfaceSize = (state) => state.surfaceSize;
2458
+ var selectLayoutConstraints = (state) => state.layoutConstraints;
2459
+ function WorkbenchLockedSlotLayer() {
2460
+ const lockedLayout = useWorkbenchSelector(selectLockedLayout);
2461
+ const surfaceSize = useWorkbenchSelector(selectSurfaceSize);
2462
+ const layoutConstraints = useWorkbenchSelector(selectLayoutConstraints);
2463
+ const slots = useMemo3(
2464
+ () => getWorkbenchLockedSlotFrames(
2465
+ lockedLayout,
2466
+ surfaceSize,
2467
+ layoutConstraints
2468
+ ),
2469
+ [layoutConstraints, lockedLayout, surfaceSize]
2470
+ );
2471
+ if (!slots) {
2472
+ return null;
2473
+ }
2474
+ return /* @__PURE__ */ jsx4("div", { "aria-hidden": true, className: "workbench-locked-slot-layer", children: slots.map((slot) => /* @__PURE__ */ jsx4(
2475
+ "div",
2476
+ {
2477
+ className: "workbench-locked-slot",
2478
+ style: {
2479
+ left: slot.frame.x,
2480
+ top: slot.frame.y,
2481
+ width: slot.frame.width,
2482
+ height: slot.frame.height
2483
+ }
2484
+ },
2485
+ slot.nodeID
2486
+ )) });
2487
+ }
2488
+
1929
2489
  // src/react/WorkbenchNodeLayer.tsx
1930
- import { Fragment as Fragment3, memo, useMemo as useMemo3 } from "react";
2490
+ import { Fragment as Fragment3, memo, useMemo as useMemo4 } from "react";
1931
2491
  import { createPortal } from "react-dom";
1932
2492
 
1933
2493
  // src/react/WorkbenchWindowFrame.tsx
@@ -1942,7 +2502,7 @@ import {
1942
2502
  TooltipTrigger,
1943
2503
  WindowTrafficLightIcon
1944
2504
  } from "@tutti-os/ui-system";
1945
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
2505
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1946
2506
  function WorkbenchWindowTrafficLights({
1947
2507
  className,
1948
2508
  close,
@@ -1952,7 +2512,7 @@ function WorkbenchWindowTrafficLights({
1952
2512
  onPointerDown,
1953
2513
  ...props
1954
2514
  }) {
1955
- return /* @__PURE__ */ jsxs2(
2515
+ return /* @__PURE__ */ jsxs3(
1956
2516
  "div",
1957
2517
  {
1958
2518
  ...props,
@@ -1966,7 +2526,7 @@ function WorkbenchWindowTrafficLights({
1966
2526
  onPointerDown?.(event);
1967
2527
  },
1968
2528
  children: [
1969
- close ? /* @__PURE__ */ jsx4(
2529
+ close ? /* @__PURE__ */ jsx5(
1970
2530
  WorkbenchWindowTrafficLightButton,
1971
2531
  {
1972
2532
  action: "close",
@@ -1974,7 +2534,7 @@ function WorkbenchWindowTrafficLights({
1974
2534
  tone: "close"
1975
2535
  }
1976
2536
  ) : null,
1977
- minimize ? /* @__PURE__ */ jsx4(
2537
+ minimize ? /* @__PURE__ */ jsx5(
1978
2538
  WorkbenchWindowTrafficLightButton,
1979
2539
  {
1980
2540
  action: "minimize",
@@ -1982,7 +2542,7 @@ function WorkbenchWindowTrafficLights({
1982
2542
  tone: "minimize"
1983
2543
  }
1984
2544
  ) : null,
1985
- maximize ? /* @__PURE__ */ jsx4(
2545
+ maximize ? /* @__PURE__ */ jsx5(
1986
2546
  WorkbenchWindowTrafficLightButton,
1987
2547
  {
1988
2548
  action: "fullscreen",
@@ -2010,7 +2570,7 @@ function WorkbenchWindowTrafficLightButton({
2010
2570
  event.stopPropagation();
2011
2571
  };
2012
2572
  const iconName = tone === "maximize" ? input.pressed ? "unfullscreen" : "fullscreen" : tone;
2013
- const button = /* @__PURE__ */ jsx4(
2573
+ const button = /* @__PURE__ */ jsx5(
2014
2574
  "button",
2015
2575
  {
2016
2576
  "aria-label": input.label,
@@ -2023,7 +2583,7 @@ function WorkbenchWindowTrafficLightButton({
2023
2583
  onClick: handleClick,
2024
2584
  onDoubleClick: (event) => event.stopPropagation(),
2025
2585
  onPointerDown: stopPointer,
2026
- children: /* @__PURE__ */ jsx4(
2586
+ children: /* @__PURE__ */ jsx5(
2027
2587
  WindowTrafficLightIcon,
2028
2588
  {
2029
2589
  "aria-hidden": "true",
@@ -2034,14 +2594,14 @@ function WorkbenchWindowTrafficLightButton({
2034
2594
  )
2035
2595
  }
2036
2596
  );
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 })
2597
+ return /* @__PURE__ */ jsx5(TooltipProvider, { delayDuration: 250, skipDelayDuration: 0, children: /* @__PURE__ */ jsxs3(Tooltip, { children: [
2598
+ /* @__PURE__ */ jsx5(TooltipTrigger, { asChild: true, children: button }),
2599
+ /* @__PURE__ */ jsx5(TooltipContent, { side: "bottom", children: input.label })
2040
2600
  ] }) });
2041
2601
  }
2042
2602
 
2043
2603
  // src/react/WorkbenchWindowFullscreenToggle.tsx
2044
- import { jsx as jsx5 } from "react/jsx-runtime";
2604
+ import { jsx as jsx6 } from "react/jsx-runtime";
2045
2605
  function WorkbenchWindowFullscreenToggle({
2046
2606
  controller,
2047
2607
  disabled = false,
@@ -2050,7 +2610,7 @@ function WorkbenchWindowFullscreenToggle({
2050
2610
  }) {
2051
2611
  const isFullscreen = node.displayMode === "fullscreen";
2052
2612
  const label = i18n.t(isFullscreen ? "exitFullscreen" : "enterFullscreen");
2053
- return /* @__PURE__ */ jsx5(
2613
+ return /* @__PURE__ */ jsx6(
2054
2614
  WorkbenchWindowTrafficLights,
2055
2615
  {
2056
2616
  maximize: {
@@ -2127,16 +2687,22 @@ function useWorkbenchDrag(node, options = {}) {
2127
2687
  controller.commands.setActiveDragNode(node.id);
2128
2688
  const origin = { x: event.clientX, y: event.clientY };
2129
2689
  const initialFrame = node.frame;
2690
+ const isLockedLayoutDrag = () => {
2691
+ const lockedLayout = controller.getSnapshot().lockedLayout;
2692
+ return lockedLayout !== null && lockedLayout.nodeIDs.includes(node.id);
2693
+ };
2130
2694
  const onPointerMove = (moveEvent) => {
2131
2695
  const nextFrame = {
2132
2696
  ...initialFrame,
2133
2697
  x: initialFrame.x + moveEvent.clientX - origin.x,
2134
2698
  y: initialFrame.y + moveEvent.clientY - origin.y
2135
2699
  };
2136
- updateSnap(
2137
- { x: moveEvent.clientX, y: moveEvent.clientY },
2138
- { edgeSnapEnabled }
2139
- );
2700
+ if (!isLockedLayoutDrag()) {
2701
+ updateSnap(
2702
+ { x: moveEvent.clientX, y: moveEvent.clientY },
2703
+ { edgeSnapEnabled }
2704
+ );
2705
+ }
2140
2706
  controller.commands.dragNode(node.id, nextFrame);
2141
2707
  };
2142
2708
  const clearListeners = () => {
@@ -2147,7 +2713,9 @@ function useWorkbenchDrag(node, options = {}) {
2147
2713
  window.removeEventListener("pointercancel", cancelDrag);
2148
2714
  };
2149
2715
  const finishDrag = (upEvent) => {
2150
- if (updateSnap(
2716
+ if (isLockedLayoutDrag()) {
2717
+ controller.commands.settleLockedDrag(node.id);
2718
+ } else if (updateSnap(
2151
2719
  { x: upEvent.clientX, y: upEvent.clientY },
2152
2720
  { edgeSnapEnabled }
2153
2721
  ) !== null) {
@@ -2156,6 +2724,9 @@ function useWorkbenchDrag(node, options = {}) {
2156
2724
  clearListeners();
2157
2725
  };
2158
2726
  const cancelDrag = () => {
2727
+ if (isLockedLayoutDrag()) {
2728
+ controller.commands.settleLockedDrag(node.id);
2729
+ }
2159
2730
  clearListeners();
2160
2731
  };
2161
2732
  window.addEventListener("pointermove", onPointerMove);
@@ -2264,7 +2835,7 @@ function resolveWorkbenchWindowHeader({
2264
2835
  }
2265
2836
 
2266
2837
  // src/react/WorkbenchWindowFrame.tsx
2267
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
2838
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
2268
2839
  var resizeHandles = [
2269
2840
  "north",
2270
2841
  "east",
@@ -2336,7 +2907,7 @@ function WorkbenchWindowFrame({
2336
2907
  genie.minimizeNodeToAnchor(nodeID, minimize);
2337
2908
  }
2338
2909
  };
2339
- const defaultActions = interactive ? /* @__PURE__ */ jsxs3(
2910
+ const defaultActions = interactive ? /* @__PURE__ */ jsxs4(
2340
2911
  "div",
2341
2912
  {
2342
2913
  className: "workbench-window__traffic-light-actions",
@@ -2352,7 +2923,7 @@ function WorkbenchWindowFrame({
2352
2923
  genie: genieControls,
2353
2924
  node
2354
2925
  }) : null,
2355
- /* @__PURE__ */ jsx6(
2926
+ /* @__PURE__ */ jsx7(
2356
2927
  WorkbenchWindowFullscreenToggle,
2357
2928
  {
2358
2929
  controller,
@@ -2393,7 +2964,7 @@ function WorkbenchWindowFrame({
2393
2964
  (presentationFrame.height - node.frame.height * presentationScale) / 2
2394
2965
  ) - node.frame.y : 0;
2395
2966
  const shellTransform = presentationMode === "mission-control" && presentationFrame ? `matrix(${presentationScale}, 0, 0, ${presentationScale}, ${presentationOffsetX}, ${presentationOffsetY})` : void 0;
2396
- return /* @__PURE__ */ jsxs3(
2967
+ return /* @__PURE__ */ jsxs4(
2397
2968
  "section",
2398
2969
  {
2399
2970
  "aria-hidden": hiddenMounted || isPresentationHidden ? true : void 0,
@@ -2421,8 +2992,8 @@ function WorkbenchWindowFrame({
2421
2992
  },
2422
2993
  onPointerDown: hiddenMounted || isPresentationHidden || !interactive || presentationMode === "mission-control" ? void 0 : () => controller.commands.focusNode(node.id),
2423
2994
  children: [
2424
- /* @__PURE__ */ jsxs3("div", { className: "workbench-window-shell__content", children: [
2425
- /* @__PURE__ */ jsxs3(
2995
+ /* @__PURE__ */ jsxs4("div", { className: "workbench-window-shell__content", children: [
2996
+ /* @__PURE__ */ jsxs4(
2426
2997
  "div",
2427
2998
  {
2428
2999
  className: "workbench-window",
@@ -2434,7 +3005,7 @@ function WorkbenchWindowFrame({
2434
3005
  "data-window-drag-state": isDragging ? "dragging" : "idle",
2435
3006
  "data-window-resize-state": isResizing ? "resizing" : "idle",
2436
3007
  children: [
2437
- /* @__PURE__ */ jsx6(
3008
+ /* @__PURE__ */ jsx7(
2438
3009
  "div",
2439
3010
  {
2440
3011
  className: [
@@ -2443,19 +3014,19 @@ function WorkbenchWindowFrame({
2443
3014
  ].filter(Boolean).join(" "),
2444
3015
  onDoubleClick: shouldRenderCustomHeader || !interactive ? void 0 : onHeaderDoubleClick,
2445
3016
  onPointerDown: shouldRenderCustomHeader || !interactive ? void 0 : onDragStart,
2446
- children: shouldRenderCustomHeader ? resolvedHeader.customHeader : /* @__PURE__ */ jsxs3(Fragment2, { children: [
3017
+ children: shouldRenderCustomHeader ? resolvedHeader.customHeader : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2447
3018
  defaultActions,
2448
- /* @__PURE__ */ jsx6("div", { className: "workbench-window__title", children: node.title })
3019
+ /* @__PURE__ */ jsx7("div", { className: "workbench-window__title", children: node.title })
2449
3020
  ] })
2450
3021
  }
2451
3022
  ),
2452
- /* @__PURE__ */ jsx6("div", { className: "workbench-window__body", children })
3023
+ /* @__PURE__ */ jsx7("div", { className: "workbench-window__body", children })
2453
3024
  ]
2454
3025
  }
2455
3026
  ),
2456
- node.displayMode === "floating" && !hiddenMounted && presentationMode !== "mission-control" && interactive ? resizeHandles.map((handle) => /* @__PURE__ */ jsx6(ResizeHandle, { handle, node }, handle)) : null
3027
+ node.displayMode === "floating" && !hiddenMounted && presentationMode !== "mission-control" && interactive ? resizeHandles.map((handle) => /* @__PURE__ */ jsx7(ResizeHandle, { handle, node }, handle)) : null
2457
3028
  ] }),
2458
- presentationInteraction ? /* @__PURE__ */ jsx6(
3029
+ presentationInteraction ? /* @__PURE__ */ jsx7(
2459
3030
  "button",
2460
3031
  {
2461
3032
  "aria-label": node.title,
@@ -2466,10 +3037,10 @@ function WorkbenchWindowFrame({
2466
3037
  event.stopPropagation();
2467
3038
  presentationInteraction.onNodePress(node.id);
2468
3039
  },
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
3040
+ 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
3041
  }
2471
3042
  ) : null,
2472
- presentationInteraction?.mode === "layout" && isMissionControlSelected ? /* @__PURE__ */ jsx6(
3043
+ presentationInteraction?.mode === "layout" && isMissionControlSelected ? /* @__PURE__ */ jsx7(
2473
3044
  Checkbox,
2474
3045
  {
2475
3046
  "aria-hidden": "true",
@@ -2487,7 +3058,7 @@ function ResizeHandle({
2487
3058
  node
2488
3059
  }) {
2489
3060
  const onPointerDown = useWorkbenchResize(node, handle);
2490
- return /* @__PURE__ */ jsx6(
3061
+ return /* @__PURE__ */ jsx7(
2491
3062
  "div",
2492
3063
  {
2493
3064
  className: "workbench-window__resize-handle",
@@ -2522,7 +3093,7 @@ function stringArraysEqual(left, right) {
2522
3093
  }
2523
3094
 
2524
3095
  // src/react/WorkbenchNodeLayer.tsx
2525
- import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
3096
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2526
3097
  function WorkbenchNodeLayer({
2527
3098
  genie,
2528
3099
  edgeSnapEnabled = false,
@@ -2538,7 +3109,7 @@ function WorkbenchNodeLayer({
2538
3109
  windowChromeMode,
2539
3110
  windowChromeI18n
2540
3111
  }) {
2541
- const selectRenderedNodeIDs = useMemo3(
3112
+ const selectRenderedNodeIDs = useMemo4(
2542
3113
  () => createRenderedWorkbenchNodeIDsSelector(shouldKeepMinimizedNodeMounted),
2543
3114
  [shouldKeepMinimizedNodeMounted]
2544
3115
  );
@@ -2570,7 +3141,7 @@ function WorkbenchNodeLayer({
2570
3141
  });
2571
3142
  const snapPreviewRect = useWorkbenchSelector(selectWorkbenchSnapPreviewRect);
2572
3143
  const presentationInteraction = interactive && presentation?.mode === "mission-control" ? presentation.interaction ?? null : null;
2573
- const dialogPopoverLayer = dialogPopoverNodeIDs.length > 0 ? /* @__PURE__ */ jsx7(
3144
+ const dialogPopoverLayer = dialogPopoverNodeIDs.length > 0 ? /* @__PURE__ */ jsx8(
2574
3145
  WorkbenchNodeLayerGroup,
2575
3146
  {
2576
3147
  className: "workbench-node-layer workbench-node-layer--dialog-popover",
@@ -2588,8 +3159,8 @@ function WorkbenchNodeLayer({
2588
3159
  windowChromeMode
2589
3160
  }
2590
3161
  ) : null;
2591
- return /* @__PURE__ */ jsxs4(Fragment3, { children: [
2592
- /* @__PURE__ */ jsx7(
3162
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
3163
+ /* @__PURE__ */ jsx8(
2593
3164
  WorkbenchNodeLayerGroup,
2594
3165
  {
2595
3166
  className: "workbench-node-layer",
@@ -2629,7 +3200,7 @@ function WorkbenchNodeLayerGroup({
2629
3200
  windowChromeI18n,
2630
3201
  windowChromeMode
2631
3202
  }) {
2632
- return /* @__PURE__ */ jsxs4(
3203
+ return /* @__PURE__ */ jsxs5(
2633
3204
  "div",
2634
3205
  {
2635
3206
  className,
@@ -2641,7 +3212,7 @@ function WorkbenchNodeLayerGroup({
2641
3212
  onBackdropPress();
2642
3213
  } : void 0,
2643
3214
  children: [
2644
- snapPreviewRect ? /* @__PURE__ */ jsx7(
3215
+ snapPreviewRect ? /* @__PURE__ */ jsx8(
2645
3216
  "div",
2646
3217
  {
2647
3218
  className: "workbench-snap-preview",
@@ -2653,7 +3224,7 @@ function WorkbenchNodeLayerGroup({
2653
3224
  }
2654
3225
  }
2655
3226
  ) : null,
2656
- nodeIDs.map((nodeID) => /* @__PURE__ */ jsx7(
3227
+ nodeIDs.map((nodeID) => /* @__PURE__ */ jsx8(
2657
3228
  MemoizedWorkbenchNodeLayerItem,
2658
3229
  {
2659
3230
  fullscreenHeaderMode,
@@ -2702,7 +3273,7 @@ function WorkbenchNodeLayerItem({
2702
3273
  if (!node) {
2703
3274
  return null;
2704
3275
  }
2705
- return /* @__PURE__ */ jsx7(
3276
+ return /* @__PURE__ */ jsx8(
2706
3277
  WorkbenchWindowFrame,
2707
3278
  {
2708
3279
  edgeSnapEnabled,
@@ -2742,7 +3313,7 @@ var MemoizedWorkbenchNodeLayerItem = memo(
2742
3313
  );
2743
3314
 
2744
3315
  // src/react/hooks/useWorkbenchShortcuts.ts
2745
- import { useEffect as useEffect2 } from "react";
3316
+ import { useEffect as useEffect3 } from "react";
2746
3317
 
2747
3318
  // src/react/hooks/workbenchShortcutIntent.ts
2748
3319
  function resolveWorkbenchShortcutIntent(event, options = {}) {
@@ -2801,7 +3372,7 @@ function useWorkbenchShortcuts(options = {}) {
2801
3372
  const controller = useWorkbenchController();
2802
3373
  const enabled = options.enabled ?? true;
2803
3374
  const windowManagementShortcutPreset = options.windowManagementShortcutPreset ?? null;
2804
- useEffect2(() => {
3375
+ useEffect3(() => {
2805
3376
  if (!enabled) {
2806
3377
  return void 0;
2807
3378
  }
@@ -2813,9 +3384,9 @@ function useWorkbenchShortcuts(options = {}) {
2813
3384
  return;
2814
3385
  }
2815
3386
  let handled = false;
2816
- const focusedNode = selectFocusedVisibleWorkbenchNode(
2817
- controller.getSnapshot()
2818
- );
3387
+ const snapshot = controller.getSnapshot();
3388
+ const focusedNode = selectFocusedVisibleWorkbenchNode(snapshot);
3389
+ const isLockedFocusedNode = focusedNode !== null && (snapshot.lockedLayout?.nodeIDs.includes(focusedNode.id) ?? false);
2819
3390
  if (intent.type === "exitFullscreen") {
2820
3391
  if (focusedNode?.displayMode === "fullscreen") {
2821
3392
  controller.commands.exitFullscreen(focusedNode.id);
@@ -2823,15 +3394,25 @@ function useWorkbenchShortcuts(options = {}) {
2823
3394
  }
2824
3395
  } else if (intent.type === "applyFocusedSnapTarget") {
2825
3396
  if (focusedNode) {
2826
- controller.commands.applySnapTarget(
2827
- focusedNode.id,
2828
- intent.snapTarget
2829
- );
3397
+ const lockedDirection = isLockedFocusedNode ? resolveLockedMoveDirection(intent.snapTarget) : null;
3398
+ if (lockedDirection) {
3399
+ controller.commands.moveLockedNode(focusedNode.id, lockedDirection);
3400
+ } else {
3401
+ controller.commands.applySnapTarget(
3402
+ focusedNode.id,
3403
+ intent.snapTarget
3404
+ );
3405
+ }
2830
3406
  handled = true;
2831
3407
  }
2832
3408
  } else if (intent.type === "applyFocusedQuickLayout") {
2833
3409
  if (focusedNode) {
2834
- controller.commands.applyQuickLayout(focusedNode.id, intent.target);
3410
+ const lockedDirection = isLockedFocusedNode ? resolveLockedMoveDirection(intent.target) : null;
3411
+ if (lockedDirection) {
3412
+ controller.commands.moveLockedNode(focusedNode.id, lockedDirection);
3413
+ } else {
3414
+ controller.commands.applyQuickLayout(focusedNode.id, intent.target);
3415
+ }
2835
3416
  handled = true;
2836
3417
  }
2837
3418
  } else {
@@ -2849,6 +3430,20 @@ function useWorkbenchShortcuts(options = {}) {
2849
3430
  };
2850
3431
  }, [controller, enabled, windowManagementShortcutPreset]);
2851
3432
  }
3433
+ function resolveLockedMoveDirection(target) {
3434
+ switch (target) {
3435
+ case "left":
3436
+ return "left";
3437
+ case "right":
3438
+ return "right";
3439
+ case "top":
3440
+ return "up";
3441
+ case "bottom":
3442
+ return "down";
3443
+ default:
3444
+ return null;
3445
+ }
3446
+ }
2852
3447
 
2853
3448
  // src/react/hooks/useWorkbenchSurfaceSize.ts
2854
3449
  import { useLayoutEffect as useLayoutEffect3, useRef as useRef3 } from "react";
@@ -2885,7 +3480,7 @@ function useWorkbenchSurfaceSize(onSizeChange) {
2885
3480
  // src/react/useWorkbenchGenieAnimation.tsx
2886
3481
  import {
2887
3482
  useCallback as useCallback6,
2888
- useEffect as useEffect3,
3483
+ useEffect as useEffect4,
2889
3484
  useRef as useRef4,
2890
3485
  useState as useState4
2891
3486
  } from "react";
@@ -3216,7 +3811,7 @@ function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
3216
3811
  }
3217
3812
 
3218
3813
  // src/react/useWorkbenchGenieAnimation.tsx
3219
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
3814
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
3220
3815
  var genieDurationMs = 400;
3221
3816
  var previewCaptureRaceTimeoutMs = 120;
3222
3817
  var scaleMinimizeDurationMs = 220;
@@ -4088,7 +4683,7 @@ function useWorkbenchGenieAnimation({
4088
4683
  },
4089
4684
  [stopAnimation]
4090
4685
  );
4091
- useEffect3(() => () => stopAnimation(false), [stopAnimation]);
4686
+ useEffect4(() => () => stopAnimation(false), [stopAnimation]);
4092
4687
  const startOpenOrRestoreAnimation = useCallback6(
4093
4688
  async (nodeID, anchorKey, generation, dockRectFallback, minimizedNode) => {
4094
4689
  const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
@@ -4735,7 +5330,7 @@ function useWorkbenchGenieAnimation({
4735
5330
  writeMinimizedGenieTexture
4736
5331
  ]
4737
5332
  );
4738
- useEffect3(
5333
+ useEffect4(
4739
5334
  () => () => {
4740
5335
  for (const timer of minimizedDockEnterAnimationTimersRef.current.values()) {
4741
5336
  clearTimeout(timer);
@@ -4748,8 +5343,8 @@ function useWorkbenchGenieAnimation({
4748
5343
  );
4749
5344
  return {
4750
5345
  genieLayer: typeof document === "undefined" ? null : createPortal2(
4751
- /* @__PURE__ */ jsxs5(Fragment4, { children: [
4752
- /* @__PURE__ */ jsx8(
5346
+ /* @__PURE__ */ jsxs6(Fragment4, { children: [
5347
+ /* @__PURE__ */ jsx9(
4753
5348
  "canvas",
4754
5349
  {
4755
5350
  ref: canvasRef,
@@ -4758,7 +5353,7 @@ function useWorkbenchGenieAnimation({
4758
5353
  "aria-hidden": true
4759
5354
  }
4760
5355
  ),
4761
- pendingRenderedPreviewCapture ? /* @__PURE__ */ jsx8(
5356
+ pendingRenderedPreviewCapture ? /* @__PURE__ */ jsx9(
4762
5357
  "div",
4763
5358
  {
4764
5359
  ref: renderedPreviewCaptureElementRef,
@@ -4794,7 +5389,7 @@ function useWorkbenchGenieAnimation({
4794
5389
  }
4795
5390
 
4796
5391
  // src/react/WorkbenchSurface.tsx
4797
- import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
5392
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
4798
5393
  function WorkbenchSurface({
4799
5394
  captureNodePreviewImage,
4800
5395
  className,
@@ -4829,7 +5424,7 @@ function WorkbenchSurface({
4829
5424
  windowChromeMode,
4830
5425
  windowChromeI18n
4831
5426
  }) {
4832
- return /* @__PURE__ */ jsx9(WorkbenchProvider, { controller, children: /* @__PURE__ */ jsx9(
5427
+ return /* @__PURE__ */ jsx10(WorkbenchProvider, { controller, children: /* @__PURE__ */ jsx10(
4833
5428
  WorkbenchSurfaceInner,
4834
5429
  {
4835
5430
  captureNodePreviewImage,
@@ -4922,7 +5517,7 @@ function WorkbenchSurfaceInner({
4922
5517
  enabled: (shortcutsEnabled ?? true) && interactive,
4923
5518
  windowManagementShortcutPreset: windowManagement?.shortcutPreset ?? null
4924
5519
  });
4925
- useEffect4(() => {
5520
+ useEffect5(() => {
4926
5521
  if (!layoutConstraints) {
4927
5522
  return;
4928
5523
  }
@@ -4935,7 +5530,7 @@ function WorkbenchSurfaceInner({
4935
5530
  wallpaper.fit ?? "cover"
4936
5531
  )
4937
5532
  } : void 0;
4938
- return /* @__PURE__ */ jsxs6(
5533
+ return /* @__PURE__ */ jsxs7(
4939
5534
  "div",
4940
5535
  {
4941
5536
  ref,
@@ -4944,7 +5539,7 @@ function WorkbenchSurfaceInner({
4944
5539
  "data-presentation-mode": presentation?.mode ?? "default",
4945
5540
  "data-workbench-interactive": interactive ? "true" : "false",
4946
5541
  children: [
4947
- wallpaper ? /* @__PURE__ */ jsx9(
5542
+ wallpaper ? /* @__PURE__ */ jsx10(
4948
5543
  "div",
4949
5544
  {
4950
5545
  className: "workbench-surface__wallpaper",
@@ -4952,9 +5547,10 @@ function WorkbenchSurfaceInner({
4952
5547
  "aria-hidden": true
4953
5548
  }
4954
5549
  ) : null,
4955
- renderTopChrome ? /* @__PURE__ */ jsx9("div", { className: "workbench-surface__top-chrome", children: renderTopChrome() }) : null,
5550
+ renderTopChrome ? /* @__PURE__ */ jsx10("div", { className: "workbench-surface__top-chrome", children: renderTopChrome() }) : null,
4956
5551
  renderBackdrop ? renderBackdrop() : null,
4957
- /* @__PURE__ */ jsx9(
5552
+ presentation?.mode === "mission-control" ? null : /* @__PURE__ */ jsx10(WorkbenchLockedSlotLayer, {}),
5553
+ /* @__PURE__ */ jsx10(
4958
5554
  WorkbenchNodeLayer,
4959
5555
  {
4960
5556
  genie,
@@ -4972,7 +5568,7 @@ function WorkbenchSurfaceInner({
4972
5568
  windowChromeI18n
4973
5569
  }
4974
5570
  ),
4975
- /* @__PURE__ */ jsx9(
5571
+ /* @__PURE__ */ jsx10(
4976
5572
  WorkbenchDockFrame,
4977
5573
  {
4978
5574
  dockPlacement,
@@ -4981,7 +5577,7 @@ function WorkbenchSurfaceInner({
4981
5577
  renderDock
4982
5578
  }
4983
5579
  ),
4984
- renderBottomChrome ? /* @__PURE__ */ jsx9("div", { className: "workbench-surface__bottom-chrome", children: renderBottomChrome() }) : null,
5580
+ renderBottomChrome ? /* @__PURE__ */ jsx10("div", { className: "workbench-surface__bottom-chrome", children: renderBottomChrome() }) : null,
4985
5581
  renderOverlay ? renderOverlay() : null,
4986
5582
  genie.genieLayer
4987
5583
  ]
@@ -5146,7 +5742,7 @@ function resolveHostClosePreparer(contributions) {
5146
5742
  }
5147
5743
 
5148
5744
  // src/host/useWorkbenchHostRuntime.ts
5149
- import { useEffect as useEffect5, useMemo as useMemo4, useState as useState5 } from "react";
5745
+ import { useEffect as useEffect6, useMemo as useMemo5, useState as useState5 } from "react";
5150
5746
 
5151
5747
  // src/store/createDerivedSnapshotGetter.ts
5152
5748
  function createDerivedSnapshotGetter(input) {
@@ -5184,8 +5780,8 @@ function createWorkbenchHostMissionControlAdapter(input) {
5184
5780
  }
5185
5781
  });
5186
5782
  return {
5187
- applyLayoutPreset(nodeIds, preset) {
5188
- input.controller.commands.applyLayoutPreset(nodeIds, preset);
5783
+ applyLayoutPreset(nodeIds, preset, lock) {
5784
+ input.controller.commands.applyLayoutPreset(nodeIds, preset, lock);
5189
5785
  },
5190
5786
  focusNode(nodeId) {
5191
5787
  if (input.activateNode) {
@@ -7028,7 +7624,7 @@ function useWorkbenchHostRuntime({
7028
7624
  }) {
7029
7625
  const [externalStateRevision, bumpExternalStateRevision] = useState5(0);
7030
7626
  const [, bumpHydrationRevision] = useState5(0);
7031
- const hostSession = useMemo4(() => {
7627
+ const hostSession = useMemo5(() => {
7032
7628
  logWorkbenchHostDebug("create-session", debugDiagnostics, {
7033
7629
  nodeTypeIDs: nodes.map((node) => node.typeId),
7034
7630
  projectedNodeCount: projectedNodes?.length ?? 0,
@@ -7053,32 +7649,32 @@ function useWorkbenchHostRuntime({
7053
7649
  snapshotRepository,
7054
7650
  workspaceId
7055
7651
  ]);
7056
- const hostI18n = useMemo4(() => createWorkbenchHostI18nRuntime(i18n), [i18n]);
7057
- const missionControlI18n = useMemo4(
7652
+ const hostI18n = useMemo5(() => createWorkbenchHostI18nRuntime(i18n), [i18n]);
7653
+ const missionControlI18n = useMemo5(
7058
7654
  () => createWorkbenchMissionControlI18nRuntime(i18n),
7059
7655
  [i18n]
7060
7656
  );
7061
- const windowChromeI18n = useMemo4(
7657
+ const windowChromeI18n = useMemo5(
7062
7658
  () => createWorkbenchWindowChromeI18nRuntime(i18n),
7063
7659
  [i18n]
7064
7660
  );
7065
- const nodeDefinitionByType = useMemo4(
7661
+ const nodeDefinitionByType = useMemo5(
7066
7662
  () => new Map(nodes.map((definition) => [definition.typeId, definition])),
7067
7663
  [nodes]
7068
7664
  );
7069
7665
  const isHydrating = hostSession.isHydrating?.() ?? false;
7070
- const missionControlAdapter = useMemo4(
7666
+ const missionControlAdapter = useMemo5(
7071
7667
  () => missionControlEnabled && !isHydrating ? createWorkbenchHostMissionControlAdapter({
7072
7668
  activateNode: hostSession.activateNode.bind(hostSession),
7073
7669
  controller: hostSession.controller
7074
7670
  }) : null,
7075
7671
  [hostSession.controller, isHydrating, missionControlEnabled]
7076
7672
  );
7077
- const chromeController = useMemo4(
7673
+ const chromeController = useMemo5(
7078
7674
  () => isHydrating ? createReadOnlyWorkbenchController(hostSession.controller) : hostSession.controller,
7079
7675
  [hostSession.controller, isHydrating]
7080
7676
  );
7081
- const chromeContext = useMemo4(
7677
+ const chromeContext = useMemo5(
7082
7678
  () => ({
7083
7679
  activateNode: hostSession.activateNode.bind(hostSession),
7084
7680
  controller: chromeController,
@@ -7087,7 +7683,7 @@ function useWorkbenchHostRuntime({
7087
7683
  }),
7088
7684
  [chromeController, hostSession]
7089
7685
  );
7090
- useEffect5(() => {
7686
+ useEffect6(() => {
7091
7687
  let isCurrent = true;
7092
7688
  void hostSession.load().finally(() => {
7093
7689
  if (isCurrent) {
@@ -7102,13 +7698,13 @@ function useWorkbenchHostRuntime({
7102
7698
  hostSession.dispose();
7103
7699
  };
7104
7700
  }, [debugDiagnostics, hostSession, workspaceId]);
7105
- useEffect5(() => {
7701
+ useEffect6(() => {
7106
7702
  onHandleReady?.(hostSession);
7107
7703
  return () => {
7108
7704
  onHandleReady?.(null);
7109
7705
  };
7110
7706
  }, [hostSession, onHandleReady]);
7111
- useEffect5(() => {
7707
+ useEffect6(() => {
7112
7708
  if (!onMissionControlAdapterReady) {
7113
7709
  return void 0;
7114
7710
  }
@@ -7117,10 +7713,10 @@ function useWorkbenchHostRuntime({
7117
7713
  onMissionControlAdapterReady(null);
7118
7714
  };
7119
7715
  }, [missionControlAdapter, onMissionControlAdapterReady]);
7120
- useEffect5(() => {
7716
+ useEffect6(() => {
7121
7717
  hostSession.reconcileProjectedNodes(projectedNodes ?? []);
7122
7718
  }, [hostSession, projectedNodes]);
7123
- useEffect5(() => {
7719
+ useEffect6(() => {
7124
7720
  if (!externalStateSource?.subscribe) {
7125
7721
  return void 0;
7126
7722
  }
@@ -7176,14 +7772,14 @@ function logWorkbenchHostDebug(event, debugDiagnostics, payload) {
7176
7772
  }
7177
7773
 
7178
7774
  // src/host/useWorkbenchHostSurfaceRenderers.tsx
7179
- import { Component, useCallback as useCallback11, useMemo as useMemo6 } from "react";
7775
+ import { Component, useCallback as useCallback11, useMemo as useMemo7 } from "react";
7180
7776
 
7181
7777
  // src/host/WorkbenchHostDock.tsx
7182
7778
  import {
7183
7779
  useCallback as useCallback10,
7184
- useEffect as useEffect9,
7780
+ useEffect as useEffect10,
7185
7781
  useLayoutEffect as useLayoutEffect5,
7186
- useMemo as useMemo5,
7782
+ useMemo as useMemo6,
7187
7783
  useRef as useRef8,
7188
7784
  useState as useState8
7189
7785
  } from "react";
@@ -7288,7 +7884,7 @@ function isWorkbenchDockEntryBlocked(entry) {
7288
7884
  }
7289
7885
 
7290
7886
  // src/host/dockMagnification.ts
7291
- import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef5 } from "react";
7887
+ import { useCallback as useCallback8, useEffect as useEffect7, useRef as useRef5 } from "react";
7292
7888
 
7293
7889
  // src/host/dockMagnificationBounds.ts
7294
7890
  function resolveDockMagnificationViewportBounds(viewportRect, dockPlacement) {
@@ -7888,7 +8484,7 @@ function useDockMagnification({
7888
8484
  );
7889
8485
  handleGlobalPointerMoveRef.current = handlePointerMove;
7890
8486
  handleGlobalPointerCancelRef.current = handleGlobalPointerCancel;
7891
- useEffect6(() => {
8487
+ useEffect7(() => {
7892
8488
  if (typeof document === "undefined") {
7893
8489
  return;
7894
8490
  }
@@ -8016,7 +8612,7 @@ function useDockMagnification({
8016
8612
  entryRampStartedAtRef.current = null;
8017
8613
  setMagnifyActive(false);
8018
8614
  }, [setMagnifyActive, slotRefs, stopAnimation, stopGlobalPointerTracking]);
8019
- useEffect6(
8615
+ useEffect7(
8020
8616
  () => () => {
8021
8617
  resetMagnification();
8022
8618
  },
@@ -8122,7 +8718,7 @@ function orderWorkbenchMinimizedDockNodes(input) {
8122
8718
  }
8123
8719
 
8124
8720
  // src/host/minimizedDockStackPromotion.ts
8125
- import { useEffect as useEffect7, useRef as useRef6, useState as useState6 } from "react";
8721
+ import { useEffect as useEffect8, useRef as useRef6, useState as useState6 } from "react";
8126
8722
  var minimizedDockStackPromotionDurationMs = 520;
8127
8723
  function detectMinimizedDockStackPromotion(previous, next) {
8128
8724
  const previousVisibleNodeIds = new Set(
@@ -8146,7 +8742,7 @@ function useMinimizedDockStackPromotion(slots) {
8146
8742
  const promotionTimerRef = useRef6(null);
8147
8743
  const [promotedNodeId, setPromotedNodeId] = useState6(null);
8148
8744
  const [stackDispatching, setStackDispatching] = useState6(false);
8149
- useEffect7(() => {
8745
+ useEffect8(() => {
8150
8746
  const promotedNodeId2 = detectMinimizedDockStackPromotion(
8151
8747
  previousSlotsRef.current,
8152
8748
  slots
@@ -8213,7 +8809,7 @@ function resolveWorkbenchMinimizedDockRestoreIntent(input) {
8213
8809
  import {
8214
8810
  forwardRef,
8215
8811
  useCallback as useCallback9,
8216
- useEffect as useEffect8,
8812
+ useEffect as useEffect9,
8217
8813
  useLayoutEffect as useLayoutEffect4,
8218
8814
  useRef as useRef7,
8219
8815
  useState as useState7
@@ -8362,7 +8958,7 @@ function resolveMinimizedStackTrackTranslateXPx(input) {
8362
8958
  }
8363
8959
 
8364
8960
  // src/host/WorkbenchHostDockPopup.tsx
8365
- import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
8961
+ import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
8366
8962
  var dockPopupCardWidthPx = 165;
8367
8963
  var dockPopupGridGapPx = 8;
8368
8964
  var dockPopupPanelPaddingInlinePx = 12;
@@ -8540,7 +9136,7 @@ function WorkbenchHostDockPopup({
8540
9136
  } : {}
8541
9137
  };
8542
9138
  const popupDiagnosticKey = items.map((item) => item.node.id).join("|");
8543
- useEffect8(() => {
9139
+ useEffect9(() => {
8544
9140
  logWorkbenchDockPopupDebug("dock.popup.rendered", debugDiagnostics, {
8545
9141
  hasCapturePreview: Boolean(capturePreview),
8546
9142
  itemCount: popupDiagnosticKey ? popupDiagnosticKey.split("|").length : 0,
@@ -8583,7 +9179,7 @@ function WorkbenchHostDockPopup({
8583
9179
  cardRefCallbacksRef.current.set(nodeId, callback);
8584
9180
  return callback;
8585
9181
  }, []);
8586
- useEffect8(() => {
9182
+ useEffect9(() => {
8587
9183
  if (!isLeftMinimizedStack) {
8588
9184
  return;
8589
9185
  }
@@ -8595,7 +9191,7 @@ function WorkbenchHostDockPopup({
8595
9191
  document.body.removeAttribute("data-desktop-dock-minimized-stack-open");
8596
9192
  };
8597
9193
  }, [isLeftMinimizedStack]);
8598
- useEffect8(() => {
9194
+ useEffect9(() => {
8599
9195
  const handlePointerDown = (event) => {
8600
9196
  if (!(event.target instanceof Element)) {
8601
9197
  onClose();
@@ -8623,13 +9219,13 @@ function WorkbenchHostDockPopup({
8623
9219
  const previewCaptureKey = items.map(
8624
9220
  (item) => `${item.node.id}:${previewCacheToken(item.preview)}:${item.previewRevision ?? ""}`
8625
9221
  ).join("|");
8626
- useEffect8(() => {
9222
+ useEffect9(() => {
8627
9223
  if (!isMinimizedStack) {
8628
9224
  return;
8629
9225
  }
8630
9226
  setMinimizedStackScrollOffset(initialMinimizedStackScrollOffset);
8631
9227
  }, [initialMinimizedStackScrollOffset, isMinimizedStack, items.length]);
8632
- useEffect8(() => {
9228
+ useEffect9(() => {
8633
9229
  if (!isMinimizedStack) {
8634
9230
  return;
8635
9231
  }
@@ -8650,7 +9246,7 @@ function WorkbenchHostDockPopup({
8650
9246
  viewport.addEventListener("wheel", handleWheel, { passive: false });
8651
9247
  return () => viewport.removeEventListener("wheel", handleWheel);
8652
9248
  }, [isMinimizedStack, minimizedStackMaxScrollOffset]);
8653
- useEffect8(() => {
9249
+ useEffect9(() => {
8654
9250
  if (!capturePreview || isContextMenu) {
8655
9251
  return;
8656
9252
  }
@@ -8867,7 +9463,7 @@ function WorkbenchHostDockPopup({
8867
9463
  previewCaptureKey,
8868
9464
  resolveDockPreviewCacheKey2
8869
9465
  ]);
8870
- const content = /* @__PURE__ */ jsx10(
9466
+ const content = /* @__PURE__ */ jsx11(
8871
9467
  "div",
8872
9468
  {
8873
9469
  ref: popupRootRef,
@@ -8876,7 +9472,7 @@ function WorkbenchHostDockPopup({
8876
9472
  "data-desktop-dock-popup-root": "true",
8877
9473
  "data-popup-variant": resolvedVariant,
8878
9474
  style: popupStyle,
8879
- children: /* @__PURE__ */ jsx10(
9475
+ children: /* @__PURE__ */ jsx11(
8880
9476
  "div",
8881
9477
  {
8882
9478
  "aria-label": label,
@@ -8892,7 +9488,7 @@ function WorkbenchHostDockPopup({
8892
9488
  onPointerLeave: isMinimizedStack ? () => setPointer(null) : void 0,
8893
9489
  role: "dialog",
8894
9490
  style: panelStyle,
8895
- children: isContextMenu ? /* @__PURE__ */ jsx10(
9491
+ children: isContextMenu ? /* @__PURE__ */ jsx11(
8896
9492
  WorkbenchHostDockContextMenu,
8897
9493
  {
8898
9494
  canCreateNew: showCreateNew !== false,
@@ -8915,9 +9511,9 @@ function WorkbenchHostDockPopup({
8915
9511
  showAllWindowsLabel,
8916
9512
  showOpen: showOpen === true
8917
9513
  }
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(
9514
+ ) : /* @__PURE__ */ jsxs8(Fragment5, { children: [
9515
+ /* @__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 }) }),
9516
+ isMinimizedStack ? /* @__PURE__ */ jsx11(
8921
9517
  "div",
8922
9518
  {
8923
9519
  ref: minimizedStackViewportRef,
@@ -8926,7 +9522,7 @@ function WorkbenchHostDockPopup({
8926
9522
  height: minimizedStackViewportHeightPx,
8927
9523
  ...isLeftMinimizedStack ? { paddingLeft: minimizedStackLeftGutterPx } : {}
8928
9524
  },
8929
- children: /* @__PURE__ */ jsx10(
9525
+ children: /* @__PURE__ */ jsx11(
8930
9526
  "div",
8931
9527
  {
8932
9528
  className: "desktop-dock-popup__minimized-stack-track",
@@ -8945,7 +9541,7 @@ function WorkbenchHostDockPopup({
8945
9541
  capturedPreview,
8946
9542
  Boolean(capturePreview)
8947
9543
  );
8948
- return /* @__PURE__ */ jsx10(
9544
+ return /* @__PURE__ */ jsx11(
8949
9545
  WorkbenchHostDockPopupCard,
8950
9546
  {
8951
9547
  ref: registerCard(item.node.id),
@@ -8974,7 +9570,7 @@ function WorkbenchHostDockPopup({
8974
9570
  }
8975
9571
  )
8976
9572
  }
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: [
9573
+ ) : /* @__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
9574
  items.map((item) => {
8979
9575
  const previewMemoryKey = resolveDockPopupPreviewMemoryKey(
8980
9576
  item.node,
@@ -8986,7 +9582,7 @@ function WorkbenchHostDockPopup({
8986
9582
  capturedPreview,
8987
9583
  Boolean(capturePreview)
8988
9584
  );
8989
- return /* @__PURE__ */ jsx10(
9585
+ return /* @__PURE__ */ jsx11(
8990
9586
  WorkbenchHostDockPopupCard,
8991
9587
  {
8992
9588
  ref: registerCard(item.node.id),
@@ -9001,14 +9597,14 @@ function WorkbenchHostDockPopup({
9001
9597
  item.node.id
9002
9598
  );
9003
9599
  }),
9004
- showCreateNew !== false ? /* @__PURE__ */ jsxs7(
9600
+ showCreateNew !== false ? /* @__PURE__ */ jsxs8(
9005
9601
  "button",
9006
9602
  {
9007
9603
  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
9604
  type: "button",
9009
9605
  onClick: onCreateNew,
9010
9606
  children: [
9011
- /* @__PURE__ */ jsx10(
9607
+ /* @__PURE__ */ jsx11(
9012
9608
  FileCreateIcon,
9013
9609
  {
9014
9610
  "aria-hidden": "true",
@@ -9016,7 +9612,7 @@ function WorkbenchHostDockPopup({
9016
9612
  size: 28
9017
9613
  }
9018
9614
  ),
9019
- /* @__PURE__ */ jsx10("span", { className: "text-xs font-semibold text-[var(--text-primary)]", children: newWindowLabel })
9615
+ /* @__PURE__ */ jsx11("span", { className: "text-xs font-semibold text-[var(--text-primary)]", children: newWindowLabel })
9020
9616
  ]
9021
9617
  }
9022
9618
  ) : null
@@ -9057,14 +9653,14 @@ function WorkbenchHostDockContextMenu({
9057
9653
  const hasOpenCommand = !hasOpenWindows;
9058
9654
  const hasDockActionGroup = Boolean(dockRetention) || hasNewWindowCommand || hasOpenCommand;
9059
9655
  const hasWindowActionGroup = hasOpenWindows;
9060
- return /* @__PURE__ */ jsxs7(
9656
+ return /* @__PURE__ */ jsxs8(
9061
9657
  "div",
9062
9658
  {
9063
9659
  className: "flex min-w-0 flex-col gap-1",
9064
9660
  "data-desktop-dock-context-menu": "true",
9065
9661
  role: "menu",
9066
9662
  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(
9663
+ 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
9664
  WorkbenchHostDockContextMenuItem,
9069
9665
  {
9070
9666
  checked: !item.isMinimized,
@@ -9073,12 +9669,12 @@ function WorkbenchHostDockContextMenu({
9073
9669
  },
9074
9670
  item.node.id
9075
9671
  )) }) }) : null,
9076
- hasOpenWindows && (hasDockActionGroup || hasWindowActionGroup) ? /* @__PURE__ */ jsx10(WorkbenchHostDockContextMenuSeparator, {}) : null,
9077
- dockRetention ? /* @__PURE__ */ jsx10(
9672
+ hasOpenWindows && (hasDockActionGroup || hasWindowActionGroup) ? /* @__PURE__ */ jsx11(WorkbenchHostDockContextMenuSeparator, {}) : null,
9673
+ dockRetention ? /* @__PURE__ */ jsx11(
9078
9674
  WorkbenchHostDockContextMenuItem,
9079
9675
  {
9080
9676
  checked: dockRetention.checked,
9081
- checkedIcon: /* @__PURE__ */ jsx10(
9677
+ checkedIcon: /* @__PURE__ */ jsx11(
9082
9678
  PinFilledIcon,
9083
9679
  {
9084
9680
  "aria-hidden": "true",
@@ -9086,61 +9682,61 @@ function WorkbenchHostDockContextMenu({
9086
9682
  }
9087
9683
  ),
9088
9684
  disabled: dockRetention.disabled,
9089
- icon: /* @__PURE__ */ jsx10(PinIcon, { "aria-hidden": "true", className: "size-4" }),
9685
+ icon: /* @__PURE__ */ jsx11(PinIcon, { "aria-hidden": "true", className: "size-4" }),
9090
9686
  label: dockRetention.pendingLabel ?? dockRetention.label,
9091
9687
  onSelect: onRunDockRetentionAction
9092
9688
  }
9093
9689
  ) : null,
9094
- hasNewWindowCommand ? /* @__PURE__ */ jsx10(
9690
+ hasNewWindowCommand ? /* @__PURE__ */ jsx11(
9095
9691
  WorkbenchHostDockContextMenuItem,
9096
9692
  {
9097
- icon: /* @__PURE__ */ jsx10(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9693
+ icon: /* @__PURE__ */ jsx11(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9098
9694
  label: newWindowLabel,
9099
9695
  onSelect: onCreateNew
9100
9696
  }
9101
9697
  ) : null,
9102
- hasOpenCommand ? /* @__PURE__ */ jsx10(
9698
+ hasOpenCommand ? /* @__PURE__ */ jsx11(
9103
9699
  WorkbenchHostDockContextMenuItem,
9104
9700
  {
9105
9701
  disabled: !showOpen,
9106
- icon: /* @__PURE__ */ jsx10(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9702
+ icon: /* @__PURE__ */ jsx11(FileCreateIcon, { "aria-hidden": "true", className: "size-4" }),
9107
9703
  label: openLabel,
9108
9704
  onSelect: onCreateNew
9109
9705
  }
9110
9706
  ) : null,
9111
- hasOpenWindows ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
9112
- hasDockActionGroup ? /* @__PURE__ */ jsx10(WorkbenchHostDockContextMenuSeparator, {}) : null,
9113
- canShowAllWindows && onShowAllWindows ? /* @__PURE__ */ jsx10(
9707
+ hasOpenWindows ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
9708
+ hasDockActionGroup ? /* @__PURE__ */ jsx11(WorkbenchHostDockContextMenuSeparator, {}) : null,
9709
+ canShowAllWindows && onShowAllWindows ? /* @__PURE__ */ jsx11(
9114
9710
  WorkbenchHostDockContextMenuItem,
9115
9711
  {
9116
- icon: /* @__PURE__ */ jsx10(OverviewLayoutIcon, { "aria-hidden": "true", className: "size-4" }),
9712
+ icon: /* @__PURE__ */ jsx11(OverviewLayoutIcon, { "aria-hidden": "true", className: "size-4" }),
9117
9713
  label: showAllWindowsLabel,
9118
9714
  onSelect: onShowAllWindows
9119
9715
  }
9120
9716
  ) : null,
9121
- /* @__PURE__ */ jsx10(
9717
+ /* @__PURE__ */ jsx11(
9122
9718
  WorkbenchHostDockContextMenuItem,
9123
9719
  {
9124
9720
  disabled: !canEnterFullscreen || !onEnterFullscreen,
9125
- icon: /* @__PURE__ */ jsx10(MaximizeIcon, { "aria-hidden": "true", className: "size-4" }),
9721
+ icon: /* @__PURE__ */ jsx11(MaximizeIcon, { "aria-hidden": "true", className: "size-4" }),
9126
9722
  label: fullscreenLabel,
9127
9723
  onSelect: onEnterFullscreen
9128
9724
  }
9129
9725
  ),
9130
- /* @__PURE__ */ jsx10(
9726
+ /* @__PURE__ */ jsx11(
9131
9727
  WorkbenchHostDockContextMenuItem,
9132
9728
  {
9133
9729
  disabled: !onHide,
9134
- icon: /* @__PURE__ */ jsx10(MinimizeIcon, { "aria-hidden": "true", className: "size-4" }),
9730
+ icon: /* @__PURE__ */ jsx11(MinimizeIcon, { "aria-hidden": "true", className: "size-4" }),
9135
9731
  label: hideLabel,
9136
9732
  onSelect: onHide
9137
9733
  }
9138
9734
  ),
9139
- /* @__PURE__ */ jsx10(
9735
+ /* @__PURE__ */ jsx11(
9140
9736
  WorkbenchHostDockContextMenuItem,
9141
9737
  {
9142
9738
  disabled: !onQuit,
9143
- icon: /* @__PURE__ */ jsx10(CloseIcon, { "aria-hidden": "true", className: "size-4" }),
9739
+ icon: /* @__PURE__ */ jsx11(CloseIcon, { "aria-hidden": "true", className: "size-4" }),
9144
9740
  label: quitLabel,
9145
9741
  onSelect: onQuit
9146
9742
  }
@@ -9158,7 +9754,7 @@ function WorkbenchHostDockContextMenuItem({
9158
9754
  label,
9159
9755
  onSelect
9160
9756
  }) {
9161
- return /* @__PURE__ */ jsxs7(
9757
+ return /* @__PURE__ */ jsxs8(
9162
9758
  "button",
9163
9759
  {
9164
9760
  className: cn(
@@ -9175,20 +9771,20 @@ function WorkbenchHostDockContextMenuItem({
9175
9771
  onSelect();
9176
9772
  },
9177
9773
  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(
9774
+ /* @__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
9775
  CheckIcon,
9180
9776
  {
9181
9777
  "aria-hidden": "true",
9182
9778
  className: "size-4 text-[var(--tutti-purple)]"
9183
9779
  }
9184
9780
  ) : icon ?? null }),
9185
- /* @__PURE__ */ jsx10("span", { className: "min-w-0 truncate", children: label })
9781
+ /* @__PURE__ */ jsx11("span", { className: "min-w-0 truncate", children: label })
9186
9782
  ]
9187
9783
  }
9188
9784
  );
9189
9785
  }
9190
9786
  function WorkbenchHostDockContextMenuSeparator() {
9191
- return /* @__PURE__ */ jsx10(
9787
+ return /* @__PURE__ */ jsx11(
9192
9788
  "div",
9193
9789
  {
9194
9790
  "aria-hidden": "true",
@@ -9304,7 +9900,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9304
9900
  const isMinimizedStack = variant === "minimized-stack";
9305
9901
  const [isLaunching, setIsLaunching] = useState7(false);
9306
9902
  const launchTimerRef = useRef7(null);
9307
- useEffect8(
9903
+ useEffect9(
9308
9904
  () => () => {
9309
9905
  if (launchTimerRef.current !== null) {
9310
9906
  clearTimeout(launchTimerRef.current);
@@ -9337,7 +9933,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9337
9933
  [handleSelect]
9338
9934
  );
9339
9935
  const hasReadyPreview = previewState.status === "ready";
9340
- return /* @__PURE__ */ jsxs7(
9936
+ return /* @__PURE__ */ jsxs8(
9341
9937
  "div",
9342
9938
  {
9343
9939
  ref,
@@ -9352,7 +9948,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9352
9948
  "data-minimized": item.isMinimized ? "true" : void 0,
9353
9949
  style,
9354
9950
  children: [
9355
- /* @__PURE__ */ jsxs7(
9951
+ /* @__PURE__ */ jsxs8(
9356
9952
  "div",
9357
9953
  {
9358
9954
  "aria-label": title,
@@ -9366,12 +9962,12 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9366
9962
  onClick: handleSelect,
9367
9963
  onKeyDown: handleSelectKeyDown,
9368
9964
  children: [
9369
- /* @__PURE__ */ jsx10(WorkbenchHostDockPopupCardPreview, { previewState }),
9370
- labelMode === "hover-overlay" && item.title?.trim() ? /* @__PURE__ */ jsx10(WorkbenchHostDockPopupCardLabel, { title: item.title }) : null
9965
+ /* @__PURE__ */ jsx11(WorkbenchHostDockPopupCardPreview, { previewState }),
9966
+ labelMode === "hover-overlay" && item.title?.trim() ? /* @__PURE__ */ jsx11(WorkbenchHostDockPopupCardLabel, { title: item.title }) : null
9371
9967
  ]
9372
9968
  }
9373
9969
  ),
9374
- /* @__PURE__ */ jsx10(
9970
+ /* @__PURE__ */ jsx11(
9375
9971
  Button2,
9376
9972
  {
9377
9973
  "aria-label": closeWindowLabel(title),
@@ -9385,10 +9981,10 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9385
9981
  event.stopPropagation();
9386
9982
  onCloseNode(item.node.id);
9387
9983
  },
9388
- children: /* @__PURE__ */ jsx10(CloseIcon, { className: "size-3.5" })
9984
+ children: /* @__PURE__ */ jsx11(CloseIcon, { className: "size-3.5" })
9389
9985
  }
9390
9986
  ),
9391
- item.isFocused ? /* @__PURE__ */ jsx10(
9987
+ item.isFocused ? /* @__PURE__ */ jsx11(
9392
9988
  "span",
9393
9989
  {
9394
9990
  "aria-hidden": "true",
@@ -9396,7 +9992,7 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
9396
9992
  "data-desktop-dock-popup-card-active-overlay": "true"
9397
9993
  }
9398
9994
  ) : null,
9399
- isMinimizedStack ? /* @__PURE__ */ jsx10("span", { className: "desktop-dock-popup__fan-title-tip", title, children: title }) : null
9995
+ isMinimizedStack ? /* @__PURE__ */ jsx11("span", { className: "desktop-dock-popup__fan-title-tip", title, children: title }) : null
9400
9996
  ]
9401
9997
  }
9402
9998
  );
@@ -9405,23 +10001,23 @@ function WorkbenchHostDockPopupCardPreview({
9405
10001
  previewState
9406
10002
  }) {
9407
10003
  if (previewState.status !== "ready") {
9408
- return /* @__PURE__ */ jsxs7(
10004
+ return /* @__PURE__ */ jsxs8(
9409
10005
  "span",
9410
10006
  {
9411
10007
  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
10008
  "aria-hidden": "true",
9413
10009
  "data-preview-state": previewState.status,
9414
10010
  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" })
10011
+ /* @__PURE__ */ jsx11("span", { className: "block h-[7px] w-[72%] rounded-full bg-transparency-hover" }),
10012
+ /* @__PURE__ */ jsx11("span", { className: "block h-[7px] w-[58%] rounded-full bg-transparency-hover" }),
10013
+ /* @__PURE__ */ jsx11("span", { className: "block h-[7px] w-[34%] rounded-full bg-transparency-hover" })
9418
10014
  ]
9419
10015
  }
9420
10016
  );
9421
10017
  }
9422
10018
  const preview = previewState.preview;
9423
10019
  if (preview.kind === "component") {
9424
- return /* @__PURE__ */ jsx10(
10020
+ return /* @__PURE__ */ jsx11(
9425
10021
  "span",
9426
10022
  {
9427
10023
  className: "block min-h-0 min-w-0 flex-1 overflow-hidden rounded-md",
@@ -9432,14 +10028,14 @@ function WorkbenchHostDockPopupCardPreview({
9432
10028
  }
9433
10029
  );
9434
10030
  }
9435
- return /* @__PURE__ */ jsx10(
10031
+ return /* @__PURE__ */ jsx11(
9436
10032
  "span",
9437
10033
  {
9438
10034
  className: "block min-h-0 min-w-0 flex-1 overflow-hidden rounded-md",
9439
10035
  "aria-hidden": "true",
9440
10036
  "data-preview-kind": preview.kind,
9441
10037
  "data-preview-state": previewState.status,
9442
- children: /* @__PURE__ */ jsx10(
10038
+ children: /* @__PURE__ */ jsx11(
9443
10039
  "img",
9444
10040
  {
9445
10041
  alt: "",
@@ -9452,7 +10048,7 @@ function WorkbenchHostDockPopupCardPreview({
9452
10048
  );
9453
10049
  }
9454
10050
  function WorkbenchHostDockPopupCardLabel({ title }) {
9455
- return /* @__PURE__ */ jsx10(
10051
+ return /* @__PURE__ */ jsx11(
9456
10052
  "span",
9457
10053
  {
9458
10054
  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 +10056,13 @@ function WorkbenchHostDockPopupCardLabel({ title }) {
9460
10056
  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
10057
  },
9462
10058
  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 }) })
10059
+ 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
10060
  }
9465
10061
  );
9466
10062
  }
9467
10063
 
9468
10064
  // src/host/WorkbenchHostDock.tsx
9469
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
10065
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
9470
10066
  var minimizedDockPreviewViewport = {
9471
10067
  height: 34.2,
9472
10068
  width: 46.8
@@ -9511,7 +10107,7 @@ function WorkbenchHostDock({
9511
10107
  onMissionControlRequestOpen,
9512
10108
  workspaceId
9513
10109
  }) {
9514
- const minimizedNodeIDs = useMemo5(
10110
+ const minimizedNodeIDs = useMemo6(
9515
10111
  () => new Set(context.minimizedNodes.map((node) => node.id)),
9516
10112
  [context.minimizedNodes]
9517
10113
  );
@@ -9592,7 +10188,7 @@ function WorkbenchHostDock({
9592
10188
  labelTooltipOpenTimerRef.current = null;
9593
10189
  labelTooltipScheduledPointRef.current = null;
9594
10190
  }, []);
9595
- useEffect9(
10191
+ useEffect10(
9596
10192
  () => () => {
9597
10193
  clearHoverPanelCloseTimer();
9598
10194
  clearHoverPanelOpenTimer();
@@ -9686,7 +10282,7 @@ function WorkbenchHostDock({
9686
10282
  pendingDockStateRefreshRef.current = false;
9687
10283
  setDockStateRevision((revision) => revision + 1);
9688
10284
  }, []);
9689
- useEffect9(() => {
10285
+ useEffect10(() => {
9690
10286
  if (!dockStateSource) {
9691
10287
  return void 0;
9692
10288
  }
@@ -9698,14 +10294,14 @@ function WorkbenchHostDock({
9698
10294
  setDockStateRevision((revision) => revision + 1);
9699
10295
  });
9700
10296
  }, [dockStateSource]);
9701
- const renderedDockEntries = useMemo5(
10297
+ const renderedDockEntries = useMemo6(
9702
10298
  () => dockEntries.map((entry) => {
9703
10299
  const dynamicState = dockStateSource?.getEntryState(entry.id);
9704
10300
  return dynamicState ? { ...entry, ...dynamicState } : entry;
9705
10301
  }),
9706
10302
  [dockEntries, dockStateRevision, dockStateSource]
9707
10303
  );
9708
- const resolvedEntries = useMemo5(
10304
+ const resolvedEntries = useMemo6(
9709
10305
  () => resolveWorkbenchDockEntries({
9710
10306
  dockEntries: renderedDockEntries,
9711
10307
  minimizedNodeIds: minimizedNodeIDs,
@@ -9713,7 +10309,7 @@ function WorkbenchHostDock({
9713
10309
  }),
9714
10310
  [context.nodes, minimizedNodeIDs, renderedDockEntries]
9715
10311
  );
9716
- const minimizedDockSlots = useMemo5(
10312
+ const minimizedDockSlots = useMemo6(
9717
10313
  () => resolveWorkbenchMinimizedDockSlots({
9718
10314
  nodeDefinitions,
9719
10315
  nodes: context.minimizedNodes
@@ -9721,7 +10317,7 @@ function WorkbenchHostDock({
9721
10317
  [context.minimizedNodes, nodeDefinitions]
9722
10318
  );
9723
10319
  const { promotedNodeId, stackDispatching } = useMinimizedDockStackPromotion(minimizedDockSlots);
9724
- const dockItems = useMemo5(
10320
+ const dockItems = useMemo6(
9725
10321
  () => createWorkbenchHostDockItems({
9726
10322
  minimizedDockSlots,
9727
10323
  resolvedEntries
@@ -9732,7 +10328,7 @@ function WorkbenchHostDock({
9732
10328
  dockItems,
9733
10329
  (nodeId) => context.genie.shouldAnimateMinimizedDockEnter(nodeId)
9734
10330
  );
9735
- const presentDockItemKeys = useMemo5(
10331
+ const presentDockItemKeys = useMemo6(
9736
10332
  () => presentDockItems.map((item) => item.key).join("\n"),
9737
10333
  [presentDockItems]
9738
10334
  );
@@ -9741,7 +10337,7 @@ function WorkbenchHostDock({
9741
10337
  elementRefs: wallpaperToneElementRefs,
9742
10338
  itemKeys: presentDockItemKeys
9743
10339
  });
9744
- const dockWidth = useMemo5(
10340
+ const dockWidth = useMemo6(
9745
10341
  () => resolveWorkbenchHostDockItemsWidth(dockItems),
9746
10342
  [dockItems]
9747
10343
  );
@@ -9791,10 +10387,10 @@ function WorkbenchHostDock({
9791
10387
  }
9792
10388
  dockMeasureRef.current?.removeAttribute("data-dock-hover-panel-open");
9793
10389
  }, []);
9794
- useEffect9(() => {
10390
+ useEffect10(() => {
9795
10391
  activeHoverPanelRef.current = activeHoverPanel;
9796
10392
  }, [activeHoverPanel]);
9797
- useEffect9(() => {
10393
+ useEffect10(() => {
9798
10394
  activeLabelTooltipRef.current = activeLabelTooltip;
9799
10395
  }, [activeLabelTooltip]);
9800
10396
  const closeLabelTooltipImmediate = useCallback10(
@@ -10269,7 +10865,7 @@ function WorkbenchHostDock({
10269
10865
  })()
10270
10866
  )
10271
10867
  );
10272
- useEffect9(() => {
10868
+ useEffect10(() => {
10273
10869
  const shouldSubscribe = activePopup !== null || hasMinimizedPreviewCapture;
10274
10870
  if (!shouldSubscribe || !externalStateSource?.subscribe) {
10275
10871
  return void 0;
@@ -10278,7 +10874,7 @@ function WorkbenchHostDock({
10278
10874
  setExternalStateRevision((revision) => revision + 1);
10279
10875
  });
10280
10876
  }, [activePopup, externalStateSource, hasMinimizedPreviewCapture]);
10281
- useEffect9(() => {
10877
+ useEffect10(() => {
10282
10878
  const nextAttentionIds = /* @__PURE__ */ new Set();
10283
10879
  for (const entry of renderedDockEntries) {
10284
10880
  const nextToken = entry.attentionToken ?? null;
@@ -10319,7 +10915,7 @@ function WorkbenchHostDock({
10319
10915
  );
10320
10916
  }
10321
10917
  }, [renderedDockEntries]);
10322
- useEffect9(
10918
+ useEffect10(
10323
10919
  () => () => {
10324
10920
  for (const timeout of attentionTimeouts.current.values()) {
10325
10921
  globalThis.clearTimeout(timeout);
@@ -10501,20 +11097,20 @@ function WorkbenchHostDock({
10501
11097
  instanceMode: dockContextMenuInstanceMode,
10502
11098
  matchedNodes: popupEntry.matchedNodes
10503
11099
  }).kind === "launch";
10504
- return /* @__PURE__ */ jsxs8(
11100
+ return /* @__PURE__ */ jsxs9(
10505
11101
  "div",
10506
11102
  {
10507
11103
  className: "flex justify-center pointer-events-none",
10508
11104
  "data-dock-placement": dockPlacement,
10509
11105
  children: [
10510
- /* @__PURE__ */ jsx11(
11106
+ /* @__PURE__ */ jsx12(
10511
11107
  "div",
10512
11108
  {
10513
11109
  className: "desktop-dock-plate",
10514
11110
  style: dockFrameSize === null ? void 0 : {
10515
11111
  "--desktop-dock-frame-size": `${dockFrameSize}px`
10516
11112
  },
10517
- children: /* @__PURE__ */ jsxs8(
11113
+ children: /* @__PURE__ */ jsxs9(
10518
11114
  "div",
10519
11115
  {
10520
11116
  ref: dockMeasureRef,
@@ -10540,7 +11136,7 @@ function WorkbenchHostDock({
10540
11136
  role: "toolbar",
10541
11137
  style: dockPlacement === "left" ? { height: dockWidth } : { width: dockWidth },
10542
11138
  children: [
10543
- /* @__PURE__ */ jsx11(
11139
+ /* @__PURE__ */ jsx12(
10544
11140
  "span",
10545
11141
  {
10546
11142
  className: "desktop-dock__pointer-rail",
@@ -10548,7 +11144,7 @@ function WorkbenchHostDock({
10548
11144
  "aria-hidden": true
10549
11145
  }
10550
11146
  ),
10551
- /* @__PURE__ */ jsx11(
11147
+ /* @__PURE__ */ jsx12(
10552
11148
  "button",
10553
11149
  {
10554
11150
  "aria-label": i18n.t(
@@ -10559,12 +11155,12 @@ function WorkbenchHostDock({
10559
11155
  disabled: !dockScrollState.canScrollBackward,
10560
11156
  onClick: () => scrollDockItems("backward"),
10561
11157
  type: "button",
10562
- children: dockPlacement === "left" ? /* @__PURE__ */ jsx11(ChevronUpIcon, { size: 16 }) : /* @__PURE__ */ jsx11(ArrowLeftIcon, { size: 16 })
11158
+ children: dockPlacement === "left" ? /* @__PURE__ */ jsx12(ChevronUpIcon, { size: 16 }) : /* @__PURE__ */ jsx12(ArrowLeftIcon, { size: 16 })
10563
11159
  }
10564
11160
  ),
10565
- /* @__PURE__ */ jsx11("div", { ref: dockItemsRef, className: "desktop-dock__items", children: presentDockItems.map((dockItem) => {
11161
+ /* @__PURE__ */ jsx12("div", { ref: dockItemsRef, className: "desktop-dock__items", children: presentDockItems.map((dockItem) => {
10566
11162
  if (dockItem.item.kind === "separator") {
10567
- return /* @__PURE__ */ jsx11(
11163
+ return /* @__PURE__ */ jsx12(
10568
11164
  "span",
10569
11165
  {
10570
11166
  ref: registerWallpaperToneElement(dockItem.key),
@@ -10591,7 +11187,7 @@ function WorkbenchHostDock({
10591
11187
  });
10592
11188
  const hasHoverPanel = dockEntryHasHoverPanel(entry);
10593
11189
  const labelTooltipTarget2 = hasHoverPanel ? null : dockLabelTooltipTarget(`entry:${entry.id}`, entry.label);
10594
- const dockButton2 = /* @__PURE__ */ jsx11(
11190
+ const dockButton2 = /* @__PURE__ */ jsx12(
10595
11191
  "button",
10596
11192
  {
10597
11193
  "aria-expanded": currentPopup ? true : void 0,
@@ -10750,7 +11346,7 @@ function WorkbenchHostDock({
10750
11346
  entryId: entry.id
10751
11347
  });
10752
11348
  },
10753
- children: /* @__PURE__ */ jsxs8(
11349
+ children: /* @__PURE__ */ jsxs9(
10754
11350
  "span",
10755
11351
  {
10756
11352
  className: "desktop-dock__icon-shell",
@@ -10758,7 +11354,7 @@ function WorkbenchHostDock({
10758
11354
  "data-entry-state": entry.state?.kind ?? "enabled",
10759
11355
  "aria-hidden": true,
10760
11356
  children: [
10761
- /* @__PURE__ */ jsx11("span", { className: "desktop-dock__icon-content", children: entry.icon }),
11357
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__icon-content", children: entry.icon }),
10762
11358
  renderDockBadge(
10763
11359
  entry,
10764
11360
  resolvedEntry.matchedNodes.length
@@ -10768,7 +11364,7 @@ function WorkbenchHostDock({
10768
11364
  )
10769
11365
  }
10770
11366
  );
10771
- return /* @__PURE__ */ jsx11(
11367
+ return /* @__PURE__ */ jsx12(
10772
11368
  "span",
10773
11369
  {
10774
11370
  ref: registerDockSlot(anchorKey),
@@ -10869,7 +11465,7 @@ function WorkbenchHostDock({
10869
11465
  `minimized-stack:${slot.anchorKey}`,
10870
11466
  stackLabel
10871
11467
  );
10872
- const stackButton = /* @__PURE__ */ jsx11(
11468
+ const stackButton = /* @__PURE__ */ jsx12(
10873
11469
  "span",
10874
11470
  {
10875
11471
  "aria-expanded": stackPopupActive,
@@ -10903,7 +11499,7 @@ function WorkbenchHostDock({
10903
11499
  }
10904
11500
  );
10905
11501
  },
10906
- children: /* @__PURE__ */ jsxs8(
11502
+ children: /* @__PURE__ */ jsxs9(
10907
11503
  "span",
10908
11504
  {
10909
11505
  className: "desktop-dock__minimized-stack-icon",
@@ -10918,7 +11514,7 @@ function WorkbenchHostDock({
10918
11514
  (_, index) => {
10919
11515
  const node2 = slot.nodes[index];
10920
11516
  if (index === 0 && node2) {
10921
- return /* @__PURE__ */ jsx11(
11517
+ return /* @__PURE__ */ jsx12(
10922
11518
  WorkbenchHostDockMinimizedNodePreview,
10923
11519
  {
10924
11520
  capturePreview: captureMinimizedNodePreview,
@@ -10933,7 +11529,7 @@ function WorkbenchHostDock({
10933
11529
  minimizedDockPreviewFreezeKey(node2)
10934
11530
  );
10935
11531
  }
10936
- return /* @__PURE__ */ jsx11(
11532
+ return /* @__PURE__ */ jsx12(
10937
11533
  "span",
10938
11534
  {
10939
11535
  "aria-hidden": "true",
@@ -10943,13 +11539,13 @@ function WorkbenchHostDock({
10943
11539
  );
10944
11540
  }
10945
11541
  ),
10946
- /* @__PURE__ */ jsx11("span", { className: "desktop-dock__count-badge", children: slot.nodes.length })
11542
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__count-badge", children: slot.nodes.length })
10947
11543
  ]
10948
11544
  }
10949
11545
  )
10950
11546
  }
10951
11547
  );
10952
- return /* @__PURE__ */ jsx11(
11548
+ return /* @__PURE__ */ jsx12(
10953
11549
  "span",
10954
11550
  {
10955
11551
  ref: registerDockSlot(slot.anchorKey),
@@ -11004,7 +11600,7 @@ function WorkbenchHostDock({
11004
11600
  `minimized-node:${node.id}`,
11005
11601
  node.title
11006
11602
  );
11007
- const dockButton = /* @__PURE__ */ jsx11(
11603
+ const dockButton = /* @__PURE__ */ jsx12(
11008
11604
  "span",
11009
11605
  {
11010
11606
  "aria-label": i18n.t("launch", { title: node.title }),
@@ -11065,7 +11661,7 @@ function WorkbenchHostDock({
11065
11661
  }
11066
11662
  );
11067
11663
  },
11068
- children: /* @__PURE__ */ jsx11(
11664
+ children: /* @__PURE__ */ jsx12(
11069
11665
  WorkbenchHostDockMinimizedNodePreview,
11070
11666
  {
11071
11667
  capturePreview: isPendingMinimizedNode ? void 0 : captureMinimizedNodePreview,
@@ -11079,7 +11675,7 @@ function WorkbenchHostDock({
11079
11675
  )
11080
11676
  }
11081
11677
  );
11082
- return /* @__PURE__ */ jsx11(
11678
+ return /* @__PURE__ */ jsx12(
11083
11679
  "span",
11084
11680
  {
11085
11681
  ref: registerDockSlot(slot.anchorKey),
@@ -11129,7 +11725,7 @@ function WorkbenchHostDock({
11129
11725
  dockItem.key
11130
11726
  );
11131
11727
  }) }),
11132
- /* @__PURE__ */ jsx11(
11728
+ /* @__PURE__ */ jsx12(
11133
11729
  "button",
11134
11730
  {
11135
11731
  "aria-label": i18n.t(
@@ -11140,10 +11736,10 @@ function WorkbenchHostDock({
11140
11736
  disabled: !dockScrollState.canScrollForward,
11141
11737
  onClick: () => scrollDockItems("forward"),
11142
11738
  type: "button",
11143
- children: dockPlacement === "left" ? /* @__PURE__ */ jsx11(ChevronDownIcon, { size: 16 }) : /* @__PURE__ */ jsx11(ArrowRightIcon, { size: 16 })
11739
+ children: dockPlacement === "left" ? /* @__PURE__ */ jsx12(ChevronDownIcon, { size: 16 }) : /* @__PURE__ */ jsx12(ArrowRightIcon, { size: 16 })
11144
11740
  }
11145
11741
  ),
11146
- activeHoverPanel ? /* @__PURE__ */ jsx11(
11742
+ activeHoverPanel ? /* @__PURE__ */ jsx12(
11147
11743
  WorkbenchHostDockHoverPanel,
11148
11744
  {
11149
11745
  entry: resolvedEntries.find(
@@ -11176,7 +11772,7 @@ function WorkbenchHostDock({
11176
11772
  }
11177
11773
  }
11178
11774
  ) : null,
11179
- activeLabelTooltip ? /* @__PURE__ */ jsx11(
11775
+ activeLabelTooltip ? /* @__PURE__ */ jsx12(
11180
11776
  WorkbenchHostDockLabelTooltip,
11181
11777
  {
11182
11778
  placement: dockPlacement,
@@ -11188,7 +11784,7 @@ function WorkbenchHostDock({
11188
11784
  )
11189
11785
  }
11190
11786
  ),
11191
- popupEntry && activePopup ? /* @__PURE__ */ jsx11(
11787
+ popupEntry && activePopup ? /* @__PURE__ */ jsx12(
11192
11788
  WorkbenchHostDockPopup,
11193
11789
  {
11194
11790
  anchorRect: activePopup.anchorRect,
@@ -11375,7 +11971,7 @@ function WorkbenchHostDock({
11375
11971
  variant: activePopup.kind === "context-menu" ? "context-menu" : "default"
11376
11972
  }
11377
11973
  ) : null,
11378
- activeMinimizedStackSlot && activeMinimizedStackPopup ? /* @__PURE__ */ jsx11(
11974
+ activeMinimizedStackSlot && activeMinimizedStackPopup ? /* @__PURE__ */ jsx12(
11379
11975
  WorkbenchHostDockPopup,
11380
11976
  {
11381
11977
  anchorRect: activeMinimizedStackPopup,
@@ -11479,7 +12075,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11479
12075
  const [previewImageUrl, setPreviewImageUrl] = useState8(
11480
12076
  () => deferPreview || providePreview ? null : readCachedWorkbenchNodePreviewImage(node.id)
11481
12077
  );
11482
- useEffect9(() => {
12078
+ useEffect10(() => {
11483
12079
  if (deferPreview || !providePreview || componentPreview !== void 0) {
11484
12080
  return void 0;
11485
12081
  }
@@ -11528,7 +12124,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11528
12124
  node.minimizedAtUnixMs,
11529
12125
  providePreview
11530
12126
  ]);
11531
- useEffect9(() => {
12127
+ useEffect10(() => {
11532
12128
  if (deferPreview || providePreview) {
11533
12129
  return void 0;
11534
12130
  }
@@ -11590,7 +12186,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11590
12186
  return renderMinimizedDockPreviewContent(componentPreview, className);
11591
12187
  }
11592
12188
  if (previewImageUrl) {
11593
- return /* @__PURE__ */ jsx11(
12189
+ return /* @__PURE__ */ jsx12(
11594
12190
  "span",
11595
12191
  {
11596
12192
  className: [
@@ -11599,7 +12195,7 @@ function WorkbenchHostDockMinimizedNodePreview({
11599
12195
  className
11600
12196
  ].filter(Boolean).join(" "),
11601
12197
  "aria-hidden": "true",
11602
- children: /* @__PURE__ */ jsx11(
12198
+ children: /* @__PURE__ */ jsx12(
11603
12199
  "img",
11604
12200
  {
11605
12201
  alt: "",
@@ -11614,22 +12210,22 @@ function WorkbenchHostDockMinimizedNodePreview({
11614
12210
  return renderMinimizedDockPreviewPlaceholder(className);
11615
12211
  }
11616
12212
  function renderMinimizedDockPreviewPlaceholder(className) {
11617
- return /* @__PURE__ */ jsxs8(
12213
+ return /* @__PURE__ */ jsxs9(
11618
12214
  "span",
11619
12215
  {
11620
12216
  className: ["desktop-dock__minimized-preview", className].filter(Boolean).join(" "),
11621
12217
  "aria-hidden": "true",
11622
12218
  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" })
12219
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__minimized-preview-line" }),
12220
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__minimized-preview-line desktop-dock__minimized-preview-line--short" }),
12221
+ /* @__PURE__ */ jsx12("span", { className: "desktop-dock__minimized-preview-line desktop-dock__minimized-preview-line--accent" })
11626
12222
  ]
11627
12223
  }
11628
12224
  );
11629
12225
  }
11630
12226
  function renderMinimizedDockPreviewContent(preview, className) {
11631
12227
  if (preview.kind === "image") {
11632
- return /* @__PURE__ */ jsx11(
12228
+ return /* @__PURE__ */ jsx12(
11633
12229
  "span",
11634
12230
  {
11635
12231
  className: [
@@ -11638,7 +12234,7 @@ function renderMinimizedDockPreviewContent(preview, className) {
11638
12234
  className
11639
12235
  ].filter(Boolean).join(" "),
11640
12236
  "aria-hidden": "true",
11641
- children: /* @__PURE__ */ jsx11(
12237
+ children: /* @__PURE__ */ jsx12(
11642
12238
  "img",
11643
12239
  {
11644
12240
  alt: "",
@@ -11650,7 +12246,7 @@ function renderMinimizedDockPreviewContent(preview, className) {
11650
12246
  }
11651
12247
  );
11652
12248
  }
11653
- return /* @__PURE__ */ jsx11(
12249
+ return /* @__PURE__ */ jsx12(
11654
12250
  WorkbenchHostDockFrozenComponentPreview,
11655
12251
  {
11656
12252
  className,
@@ -11670,7 +12266,7 @@ function WorkbenchHostDockFrozenComponentPreview({
11670
12266
  }
11671
12267
  setFrozenMarkup(sourceRef.current?.innerHTML ?? "");
11672
12268
  }, [frozenMarkup]);
11673
- return /* @__PURE__ */ jsx11(
12269
+ return /* @__PURE__ */ jsx12(
11674
12270
  "span",
11675
12271
  {
11676
12272
  className: [
@@ -11679,14 +12275,14 @@ function WorkbenchHostDockFrozenComponentPreview({
11679
12275
  className
11680
12276
  ].filter(Boolean).join(" "),
11681
12277
  "aria-hidden": "true",
11682
- children: frozenMarkup === null ? /* @__PURE__ */ jsx11(
12278
+ children: frozenMarkup === null ? /* @__PURE__ */ jsx12(
11683
12279
  "span",
11684
12280
  {
11685
12281
  ref: sourceRef,
11686
12282
  className: "desktop-dock__minimized-preview-freeze-source",
11687
12283
  children: preview.element
11688
12284
  }
11689
- ) : /* @__PURE__ */ jsx11(
12285
+ ) : /* @__PURE__ */ jsx12(
11690
12286
  "span",
11691
12287
  {
11692
12288
  className: "desktop-dock__minimized-preview-frozen-content",
@@ -11754,18 +12350,18 @@ function renderDockBadge(entry, matchedNodeCount) {
11754
12350
  return null;
11755
12351
  }
11756
12352
  if (badge.kind === "count") {
11757
- return /* @__PURE__ */ jsx11("span", { className: "desktop-dock__count-badge", children: badge.value });
12353
+ return /* @__PURE__ */ jsx12("span", { className: "desktop-dock__count-badge", children: badge.value });
11758
12354
  }
11759
12355
  if (badge.kind === "custom") {
11760
- return /* @__PURE__ */ jsx11("span", { className: "desktop-dock__custom-badge", children: badge.content });
12356
+ return /* @__PURE__ */ jsx12("span", { className: "desktop-dock__custom-badge", children: badge.content });
11761
12357
  }
11762
- return /* @__PURE__ */ jsx11("span", { className: "desktop-dock__status-badge", "data-status": badge.status });
12358
+ return /* @__PURE__ */ jsx12("span", { className: "desktop-dock__status-badge", "data-status": badge.status });
11763
12359
  }
11764
12360
  function WorkbenchHostDockLabelTooltip({
11765
12361
  placement,
11766
12362
  state
11767
12363
  }) {
11768
- return /* @__PURE__ */ jsx11(
12364
+ return /* @__PURE__ */ jsx12(
11769
12365
  "div",
11770
12366
  {
11771
12367
  className: "desktop-dock__label-tooltip",
@@ -11829,7 +12425,7 @@ function WorkbenchHostDockHoverPanel({
11829
12425
  }
11830
12426
  })();
11831
12427
  };
11832
- return /* @__PURE__ */ jsxs8(
12428
+ return /* @__PURE__ */ jsxs9(
11833
12429
  "div",
11834
12430
  {
11835
12431
  ref: hoverPanelRef,
@@ -11848,13 +12444,13 @@ function WorkbenchHostDockHoverPanel({
11848
12444
  "--desktop-dock-hover-panel-anchor-width": `${state.anchorRect.width}px`
11849
12445
  },
11850
12446
  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) => {
12447
+ /* @__PURE__ */ jsx12("div", { className: "desktop-dock__hover-panel-title", children: entry.label }),
12448
+ entry.state?.reason ? /* @__PURE__ */ jsx12("div", { className: "desktop-dock__hover-panel-description", children: stripDockDescriptionTerminalPunctuation(entry.state.reason) }) : null,
12449
+ entry.hoverActions?.length ? /* @__PURE__ */ jsx12("div", { className: "desktop-dock__hover-actions", children: entry.hoverActions.map((action) => {
11854
12450
  const actionKey = dockActionKey(entry.id, action.id);
11855
12451
  const isLocallyPending = pendingActionKeys.has(actionKey);
11856
12452
  const isPending = isLocallyPending || action.disabled === true && action.pendingLabel !== void 0;
11857
- return /* @__PURE__ */ jsx11(
12453
+ return /* @__PURE__ */ jsx12(
11858
12454
  Button3,
11859
12455
  {
11860
12456
  "aria-busy": isPending ? true : void 0,
@@ -12095,7 +12691,7 @@ function useDockPresenceItems(items, shouldAnimateMinimizedDockEnter) {
12095
12691
  }))
12096
12692
  );
12097
12693
  const initialized = useRef8(false);
12098
- useEffect9(() => {
12694
+ useEffect10(() => {
12099
12695
  let nextSettleMs = dockPresenceAnimationMs;
12100
12696
  setPresentItems((current) => {
12101
12697
  const filteredItems = resolveDockPresenceItems({
@@ -12397,7 +12993,7 @@ function useDockBounce(slotRefs) {
12397
12993
  },
12398
12994
  [slotRefs]
12399
12995
  );
12400
- useEffect9(
12996
+ useEffect10(
12401
12997
  () => () => {
12402
12998
  for (const anchorKey of timeoutsRef.current.keys()) {
12403
12999
  clearDockBounce(anchorKey);
@@ -12570,7 +13166,7 @@ function createWorkbenchHostNodeHeaderContext({
12570
13166
  }
12571
13167
 
12572
13168
  // src/host/WorkbenchHostWindowActions.tsx
12573
- import { jsx as jsx12 } from "react/jsx-runtime";
13169
+ import { jsx as jsx13 } from "react/jsx-runtime";
12574
13170
  function WorkbenchHostWindowActions({
12575
13171
  context,
12576
13172
  host,
@@ -12583,7 +13179,7 @@ function WorkbenchHostWindowActions({
12583
13179
  }
12584
13180
  const minimizable = definition.window?.minimizable !== false;
12585
13181
  const closable = definition.window?.closable !== false;
12586
- return /* @__PURE__ */ jsx12(
13182
+ return /* @__PURE__ */ jsx13(
12587
13183
  WorkbenchWindowTrafficLights,
12588
13184
  {
12589
13185
  close: closable ? {
@@ -12606,11 +13202,11 @@ function WorkbenchHostWindowActions({
12606
13202
  }
12607
13203
 
12608
13204
  // src/host/useWorkbenchHostSurfaceRenderers.tsx
12609
- import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
13205
+ import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
12610
13206
  function useWorkbenchHostSurfaceRenderers(input) {
12611
- const renderBottomChrome = useMemo6(() => {
13207
+ const renderBottomChrome = useMemo7(() => {
12612
13208
  const renderChrome = input.renderBottomChrome;
12613
- return renderChrome ? () => /* @__PURE__ */ jsx13(
13209
+ return renderChrome ? () => /* @__PURE__ */ jsx14(
12614
13210
  WorkbenchHostSurfaceRenderErrorBoundary,
12615
13211
  {
12616
13212
  debugDiagnostics: input.debugDiagnostics,
@@ -12621,7 +13217,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12621
13217
  fallbackKind: "bottom-chrome",
12622
13218
  resetKey: `${input.workspaceId}:bottom-chrome`,
12623
13219
  workspaceId: input.workspaceId,
12624
- children: /* @__PURE__ */ jsx13(
13220
+ children: /* @__PURE__ */ jsx14(
12625
13221
  WorkbenchHostChromeRenderer,
12626
13222
  {
12627
13223
  context: input.chromeContext,
@@ -12636,9 +13232,9 @@ function useWorkbenchHostSurfaceRenderers(input) {
12636
13232
  input.renderBottomChrome,
12637
13233
  input.workspaceId
12638
13234
  ]);
12639
- const renderTopChrome = useMemo6(() => {
13235
+ const renderTopChrome = useMemo7(() => {
12640
13236
  const renderChrome = input.renderTopChrome;
12641
- return renderChrome ? () => /* @__PURE__ */ jsx13(
13237
+ return renderChrome ? () => /* @__PURE__ */ jsx14(
12642
13238
  WorkbenchHostSurfaceRenderErrorBoundary,
12643
13239
  {
12644
13240
  debugDiagnostics: input.debugDiagnostics,
@@ -12649,7 +13245,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12649
13245
  fallbackKind: "top-chrome",
12650
13246
  resetKey: `${input.workspaceId}:top-chrome`,
12651
13247
  workspaceId: input.workspaceId,
12652
- children: /* @__PURE__ */ jsx13(
13248
+ children: /* @__PURE__ */ jsx14(
12653
13249
  WorkbenchHostChromeRenderer,
12654
13250
  {
12655
13251
  context: input.chromeContext,
@@ -12698,7 +13294,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12698
13294
  ]
12699
13295
  );
12700
13296
  const renderDock = useCallback11(
12701
- (context) => /* @__PURE__ */ jsx13(
13297
+ (context) => /* @__PURE__ */ jsx14(
12702
13298
  WorkbenchHostSurfaceRenderErrorBoundary,
12703
13299
  {
12704
13300
  debugDiagnostics: input.debugDiagnostics,
@@ -12710,7 +13306,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12710
13306
  fallbackKind: "dock",
12711
13307
  resetKey: `${input.workspaceId}:dock`,
12712
13308
  workspaceId: input.workspaceId,
12713
- children: /* @__PURE__ */ jsx13(
13309
+ children: /* @__PURE__ */ jsx14(
12714
13310
  WorkbenchHostDock,
12715
13311
  {
12716
13312
  captureNodePreviewImage,
@@ -12764,7 +13360,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12764
13360
  host: input.hostSession,
12765
13361
  workspaceId: input.workspaceId
12766
13362
  });
12767
- return /* @__PURE__ */ jsx13(
13363
+ return /* @__PURE__ */ jsx14(
12768
13364
  WorkbenchHostNodeRenderErrorBoundary,
12769
13365
  {
12770
13366
  debugDiagnostics: input.debugDiagnostics,
@@ -12775,7 +13371,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12775
13371
  }),
12776
13372
  resetKey: `${context.node.id}:${context.node.data.typeId}:${input.externalStateRevision}`,
12777
13373
  workspaceId: input.workspaceId,
12778
- children: /* @__PURE__ */ jsx13(
13374
+ children: /* @__PURE__ */ jsx14(
12779
13375
  WorkbenchHostNodeBodyRenderer,
12780
13376
  {
12781
13377
  context: bodyContext,
@@ -12795,7 +13391,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
12795
13391
  ]
12796
13392
  );
12797
13393
  const renderWindowActions = useCallback11(
12798
- (context) => /* @__PURE__ */ jsx13(
13394
+ (context) => /* @__PURE__ */ jsx14(
12799
13395
  WorkbenchHostWindowActions,
12800
13396
  {
12801
13397
  context,
@@ -12988,7 +13584,7 @@ var WorkbenchHostSurfaceRenderErrorBoundary = class extends Component {
12988
13584
  }
12989
13585
  render() {
12990
13586
  if (this.state.hasError) {
12991
- return /* @__PURE__ */ jsx13(
13587
+ return /* @__PURE__ */ jsx14(
12992
13588
  "div",
12993
13589
  {
12994
13590
  "data-workbench-surface-render-error": this.props.fallbackKind,
@@ -13047,7 +13643,7 @@ var WorkbenchHostNodeRenderErrorBoundary = class extends Component {
13047
13643
  }
13048
13644
  render() {
13049
13645
  if (this.state.hasError) {
13050
- return /* @__PURE__ */ jsxs9(
13646
+ return /* @__PURE__ */ jsxs10(
13051
13647
  "div",
13052
13648
  {
13053
13649
  "data-workbench-node-render-error": "true",
@@ -13065,7 +13661,7 @@ var WorkbenchHostNodeRenderErrorBoundary = class extends Component {
13065
13661
  width: "100%"
13066
13662
  },
13067
13663
  children: [
13068
- /* @__PURE__ */ jsx13(
13664
+ /* @__PURE__ */ jsx14(
13069
13665
  "div",
13070
13666
  {
13071
13667
  "data-workbench-node-render-error-message": "true",
@@ -13077,8 +13673,8 @@ var WorkbenchHostNodeRenderErrorBoundary = class extends Component {
13077
13673
  children: "This workspace view failed to render."
13078
13674
  }
13079
13675
  ),
13080
- /* @__PURE__ */ jsx13("div", { style: { fontSize: 12 }, children: "Try selecting another conversation or reopen the window." }),
13081
- /* @__PURE__ */ jsx13(
13676
+ /* @__PURE__ */ jsx14("div", { style: { fontSize: 12 }, children: "Try selecting another conversation or reopen the window." }),
13677
+ /* @__PURE__ */ jsx14(
13082
13678
  "button",
13083
13679
  {
13084
13680
  type: "button",
@@ -13121,7 +13717,7 @@ function WorkbenchHostChromeRenderer({
13121
13717
  }
13122
13718
 
13123
13719
  // src/host/WorkbenchHost.tsx
13124
- import { jsx as jsx14 } from "react/jsx-runtime";
13720
+ import { jsx as jsx15 } from "react/jsx-runtime";
13125
13721
  var noop3 = () => {
13126
13722
  };
13127
13723
  function WorkbenchHost({
@@ -13155,7 +13751,7 @@ function WorkbenchHost({
13155
13751
  windowManagement,
13156
13752
  workspaceId
13157
13753
  }) {
13158
- const hostRuntimeConfig = useMemo7(
13754
+ const hostRuntimeConfig = useMemo8(
13159
13755
  () => resolveWorkbenchHostRuntimeConfig({
13160
13756
  contributions,
13161
13757
  externalStateSource,
@@ -13171,7 +13767,7 @@ function WorkbenchHost({
13171
13767
  onNodeCloseRequest
13172
13768
  ]
13173
13769
  );
13174
- const hostDockEntries = useMemo7(
13770
+ const hostDockEntries = useMemo8(
13175
13771
  () => resolveWorkbenchHostDockEntries({
13176
13772
  contributions,
13177
13773
  dockEntries
@@ -13234,7 +13830,7 @@ function WorkbenchHost({
13234
13830
  });
13235
13831
  const missionControlPresence = useWorkbenchMissionControlPresence(missionControlState);
13236
13832
  const missionControlRenderedState = missionControlPresence.state;
13237
- return /* @__PURE__ */ jsx14(
13833
+ return /* @__PURE__ */ jsx15(
13238
13834
  WorkbenchSurface,
13239
13835
  {
13240
13836
  className,
@@ -13248,7 +13844,7 @@ function WorkbenchHost({
13248
13844
  missionControlPhase: missionControlPresence.phase,
13249
13845
  minimizeAnimation,
13250
13846
  presentation: missionControlState?.presentation ?? null,
13251
- renderBackdrop: missionControlRenderedState ? () => /* @__PURE__ */ jsx14(
13847
+ renderBackdrop: missionControlRenderedState ? () => /* @__PURE__ */ jsx15(
13252
13848
  WorkbenchMissionControlBackdrop,
13253
13849
  {
13254
13850
  onExitTransitionComplete: () => missionControlPresence.completeExitTransition(),
@@ -13259,7 +13855,7 @@ function WorkbenchHost({
13259
13855
  renderDock: surfaceRenderers.renderDock,
13260
13856
  renderNode: surfaceRenderers.renderNode,
13261
13857
  renderNodeGeniePreview: surfaceRenderers.renderNodeGeniePreview,
13262
- renderOverlay: missionControlRenderedState ? () => /* @__PURE__ */ jsx14(
13858
+ renderOverlay: missionControlRenderedState ? () => /* @__PURE__ */ jsx15(
13263
13859
  WorkbenchMissionControlOverlay,
13264
13860
  {
13265
13861
  i18n: missionControlI18n,