@mindexec/cli 0.2.103 → 0.2.105

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.103",
3
+ "version": "0.2.105",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -47,7 +47,7 @@
47
47
  "node": ">=20"
48
48
  },
49
49
  "dependencies": {
50
- "@mindexec/remote": "^0.1.16",
50
+ "@mindexec/remote": "^0.1.16",
51
51
  "@openai/codex-sdk": "^0.137.0",
52
52
  "chokidar": "^3.6.0",
53
53
  "cors": "^2.8.5",
@@ -1925,6 +1925,37 @@ body.is-panning .mind-map-text-overlay-v2-card.is-passive .mind-map-text-overlay
1925
1925
  caret-color: auto !important;
1926
1926
  }
1927
1927
 
1928
+ .css3d-resolution-wrapper.node-type-csv-table,
1929
+ .css3d-resolution-wrapper.node-type-csv-table > .map-node,
1930
+ .css3d-resolution-wrapper.node-type-csv-table .node-content-wrapper,
1931
+ .map-node-csv-table .node-content-wrapper--csv-table {
1932
+ min-width: 0 !important;
1933
+ min-height: 0 !important;
1934
+ max-width: 100% !important;
1935
+ max-height: 100% !important;
1936
+ box-sizing: border-box !important;
1937
+ overflow: hidden !important;
1938
+ }
1939
+
1940
+ .css3d-resolution-wrapper.node-type-csv-table .node-content-wrapper,
1941
+ .map-node-csv-table .node-content-wrapper--csv-table {
1942
+ display: flex !important;
1943
+ flex-direction: column !important;
1944
+ }
1945
+
1946
+ .css3d-resolution-wrapper.node-type-csv-table .node-response.csv-table-scroll,
1947
+ .map-node-csv-table .node-response.csv-table-scroll {
1948
+ width: 100% !important;
1949
+ height: auto !important;
1950
+ max-height: 100% !important;
1951
+ flex: 1 1 0% !important;
1952
+ min-height: 0 !important;
1953
+ overflow: auto !important;
1954
+ scrollbar-gutter: stable both-edges !important;
1955
+ padding-right: 0 !important;
1956
+ overscroll-behavior: contain;
1957
+ }
1958
+
1928
1959
  .css3d-resolution-wrapper.node-type-image,
1929
1960
  .css3d-resolution-wrapper.node-type-video,
1930
1961
  .css3d-resolution-wrapper.node-type-embed {
@@ -5,7 +5,7 @@
5
5
  const DEBUG = false;
6
6
  const FPS_DEBUG = false;
7
7
  const FRAME_PERF_DEBUG = false;
8
- const MINDMAP_CORE_BUILD_ID = '20260613-remote-monitor-gap-v214';
8
+ const MINDMAP_CORE_BUILD_ID = '20260616-live-template-overlay-v565';
9
9
  const CanvasPhase = Object.freeze({
10
10
  Booting: 'booting',
11
11
  BoardFileLoading: 'board-file-loading',
@@ -5037,6 +5037,9 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5037
5037
  const shouldRenderPassiveDomTextOverlay =
5038
5038
  useTextOverlayV2 &&
5039
5039
  window.MindMapTextOverlayV2?.shouldRenderPassiveDomOverlays?.(this) === true;
5040
+ const hasLiveInteractiveDomOverlay =
5041
+ useTextOverlayV2 &&
5042
+ window.MindMapTextOverlayV2?.hasLiveInteractiveOverlay?.(this) === true;
5040
5043
  const overlayV2State = useTextOverlayV2 ? (this._textOverlayV2State || null) : null;
5041
5044
  const hasOverlayV2DirtyState = !!(
5042
5045
  overlayV2State && (
@@ -5097,7 +5100,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5097
5100
  this.isDraggingMultipleNodes === true ||
5098
5101
  isCameraMoving ||
5099
5102
  this.isResizing === true) &&
5100
- !isInLodMode &&
5103
+ (!isInLodMode || hasLiveInteractiveDomOverlay) &&
5101
5104
  !hasEditingOverlay &&
5102
5105
  !this.isWindowResizing;
5103
5106
  if ((this._suppressPassiveDomOverlayDuringZoom === true) !== shouldSuppressPassiveOverlayDuringCameraMotion) {
@@ -5149,7 +5152,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5149
5152
  const shouldRefreshPassiveDomTextOverlay =
5150
5153
  shouldRenderPassiveDomTextOverlay &&
5151
5154
  !isPassiveOverlaySuppressed &&
5152
- !isInLodMode &&
5155
+ (!isInLodMode || hasLiveInteractiveDomOverlay) &&
5153
5156
  shouldUpdateCss3d &&
5154
5157
  !shouldUsePassiveOverlayCameraFastPath;
5155
5158
  const shouldUsePassiveOverlayMotionHint =
@@ -5349,7 +5352,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5349
5352
  shouldFallbackToFullPassiveOverlayRefresh &&
5350
5353
  shouldRenderPassiveDomTextOverlay &&
5351
5354
  !hasOverlayFocus &&
5352
- !isInLodMode &&
5355
+ (!isInLodMode || hasLiveInteractiveDomOverlay) &&
5353
5356
  (isInteractiveFrame || this.isPanning === true || this.isZooming === true || visibleOverlayCount > 80);
5354
5357
  if (useTextOverlayV2 && isPassiveOverlaySuppressed) {
5355
5358
  this._usedPassiveOverlayCameraFastPathLastFrame = false;
@@ -5367,7 +5370,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5367
5370
  // full overlay layout update instead of waiting for the
5368
5371
  // next deferred refresh window.
5369
5372
  window.MindMapTextOverlayV2.updateFrame(this);
5370
- if (shouldRenderPassiveDomTextOverlay && !hasOverlayFocus && !isInLodMode) {
5373
+ if (shouldRenderPassiveDomTextOverlay && !hasOverlayFocus && (!isInLodMode || hasLiveInteractiveDomOverlay)) {
5371
5374
  this._lastPassiveOverlayFullRefreshAt = frameStart;
5372
5375
  this._overlayDebugRefreshAgeMs = 0;
5373
5376
  this._overlayDebugRefreshDeferred = false;
@@ -384,6 +384,34 @@
384
384
  .csv-table-scroll:hover::-webkit-scrollbar-thumb {
385
385
  background: rgba(71, 85, 105, 0.48);
386
386
  }
387
+ .css3d-resolution-wrapper.node-type-csv-table,
388
+ .css3d-resolution-wrapper.node-type-csv-table > .map-node,
389
+ .css3d-resolution-wrapper.node-type-csv-table .node-content-wrapper,
390
+ .map-node-csv-table .node-content-wrapper--csv-table {
391
+ min-width: 0 !important;
392
+ min-height: 0 !important;
393
+ max-width: 100% !important;
394
+ max-height: 100% !important;
395
+ box-sizing: border-box !important;
396
+ overflow: hidden !important;
397
+ }
398
+ .css3d-resolution-wrapper.node-type-csv-table .node-content-wrapper,
399
+ .map-node-csv-table .node-content-wrapper--csv-table {
400
+ display: flex !important;
401
+ flex-direction: column !important;
402
+ }
403
+ .css3d-resolution-wrapper.node-type-csv-table .node-response.csv-table-scroll,
404
+ .map-node-csv-table .node-response.csv-table-scroll {
405
+ width: 100% !important;
406
+ height: auto !important;
407
+ max-height: 100% !important;
408
+ flex: 1 1 0% !important;
409
+ min-height: 0 !important;
410
+ overflow: auto !important;
411
+ scrollbar-gutter: stable both-edges !important;
412
+ padding-right: 0 !important;
413
+ overscroll-behavior: contain;
414
+ }
387
415
  .csv-table {
388
416
  width: max-content;
389
417
  min-width: 100%;
@@ -3870,7 +3898,7 @@
3870
3898
  const NEUTRAL_SELECTION_GLOW_RGB_SOFT = '191, 219, 254';
3871
3899
  const CSS3D_WRAPPER_TRANSITION = 'box-shadow .22s ease, filter .22s ease';
3872
3900
  const CSS3D_WRAPPER_WEBKIT_TRANSITION = '-webkit-box-shadow .22s ease, -webkit-filter .22s ease';
3873
- const TEXT_OVERLAY_SUPPORTED_TYPES = new Set(['text', 'markdown', 'note', 'code', 'memo']);
3901
+ const TEXT_OVERLAY_SUPPORTED_TYPES = new Set(['text', 'markdown', 'note', 'code', 'memo', 'templatelauncher']);
3874
3902
  const TEXT_SELECTION_OVERLAY_SUPPORTED_TYPES = new Set(['text', 'markdown']);
3875
3903
  const TEXT_INTERACTION_SCROLLABLE_SELECTORS = '.node-response, .note-content, .markdown-body, .prose, .note-textarea, .code-body, .code-content, .csv-table-scroll, .csv-table-scroll *, .pdf-content, .text-content, .file-content, .map-node-memo__body, .map-node-memo__body-view, .map-node-memo__agent-plan-body, .map-node-memo__agent-console-body, pre, code';
3876
3904
  const TEXT_INTERACTION_CONTENT_SELECTORS = '.node-response, .code-body, .text-content, .markdown-body, .prose, .csv-table-scroll, .csv-table-cell';
@@ -3978,6 +4006,11 @@
3978
4006
  || semanticType === REMOTE_FLEET_DEVICE_SEMANTIC_TYPE;
3979
4007
  }
3980
4008
 
4009
+ function isTemplateLauncherNode(nodeModel) {
4010
+ const contentType = String(nodeModel?.contentType ?? nodeModel?.ContentType ?? '').trim().toLowerCase();
4011
+ return contentType === 'templatelauncher' || isRemoteFleetMonitorNode(nodeModel);
4012
+ }
4013
+
3981
4014
  function isBusinessAutomationContextSourceNode(nodeModel) {
3982
4015
  if (!nodeModel || isBusinessAutomationNode(nodeModel) || isRemoteFleetNode(nodeModel)) {
3983
4016
  return false;
@@ -4048,6 +4081,10 @@
4048
4081
  return 'none';
4049
4082
  }
4050
4083
 
4084
+ if (isTemplateLauncherNode(nodeEntry?.model)) {
4085
+ return 'live-template';
4086
+ }
4087
+
4051
4088
  if (getTextOverlayRenderMode(nodeEntry) === 'memo') {
4052
4089
  // Memo cards rely on the canonical CSS3D shell for their rounded
4053
4090
  // body surface and selection glow. Passive readonly overlays only
@@ -19589,14 +19626,18 @@
19589
19626
 
19590
19627
  // 콘텐츠 래퍼 생성
19591
19628
  const contentWrapper = document.createElement('div');
19592
- contentWrapper.className = 'node-content-wrapper';
19629
+ contentWrapper.className = isCsvTableNode
19630
+ ? 'node-content-wrapper node-content-wrapper--csv-table'
19631
+ : 'node-content-wrapper';
19593
19632
  contentWrapper.style.cssText = `
19594
19633
  width: 100%;
19595
19634
  height: 100%;
19635
+ max-height: 100%;
19596
19636
  overflow: hidden;
19597
19637
  display: ${isMediaNode ? 'block' : 'flex'};
19598
19638
  flex-direction: ${isMediaNode ? 'initial' : 'column'};
19599
19639
  min-height: ${isMediaNode ? 'auto' : '0'};
19640
+ min-width: 0;
19600
19641
  position: ${isMediaNode ? 'relative' : 'static'};
19601
19642
  transform: none;
19602
19643
  will-change: auto;
@@ -19691,10 +19732,13 @@
19691
19732
  responseDiv.className = 'node-response csv-table-scroll';
19692
19733
  responseDiv.style.cssText = `
19693
19734
  width: 100%;
19694
- height: 100%;
19695
- flex: 1 1 auto;
19735
+ height: auto;
19736
+ max-height: 100%;
19737
+ flex: 1 1 0%;
19696
19738
  min-height: 0;
19697
19739
  overflow: auto;
19740
+ overscroll-behavior: contain;
19741
+ scrollbar-gutter: stable both-edges;
19698
19742
  pointer-events: auto;
19699
19743
  box-sizing: border-box;
19700
19744
  user-select: text;
@@ -13,6 +13,8 @@
13
13
  const PASSIVE_OVERLAY_OVERLAP_MIN_PX = 2;
14
14
  const PASSIVE_OVERLAY_OVERLAP_MIN_AREA_PX = 16;
15
15
  const PASSIVE_OVERLAY_STACK_Z_SCALE = 10000;
16
+ const LIVE_TEMPLATE_OVERLAY_MODE = 'live-template';
17
+ const REMOTE_FLEET_SEMANTIC_TYPE = 'RemoteFleetMonitor';
16
18
  const log = DEBUG ? console.log.bind(console, '[MindMapTextOverlayV2]') : () => { };
17
19
  let _projCornerTopLeft = null;
18
20
  let _projCornerTopRight = null;
@@ -79,6 +81,17 @@
79
81
  return String(metadata?.SemanticType || metadata?.semanticType || model?.SemanticType || model?.semanticType || '').trim();
80
82
  }
81
83
 
84
+ function isLiveInteractiveOverlayEntry(entry) {
85
+ const type = getContentType(entry);
86
+ const semanticType = getNodeSemanticType(entry);
87
+ return type === 'templatelauncher' || semanticType === REMOTE_FLEET_SEMANTIC_TYPE;
88
+ }
89
+
90
+ function isLiveInteractiveOverlayMode(mode) {
91
+ const normalized = String(mode || '').trim().toLowerCase();
92
+ return normalized === LIVE_TEMPLATE_OVERLAY_MODE || normalized === 'live';
93
+ }
94
+
82
95
  function isAgentStyledMemoEntry(entry) {
83
96
  const semanticType = getNodeSemanticType(entry);
84
97
  return semanticType === 'MindCanvasAgent'
@@ -172,6 +185,44 @@
172
185
  return module?.useDomTextOverlay === true;
173
186
  }
174
187
 
188
+ function hasVisibleLiveInteractiveOverlayCandidate(module) {
189
+ const visibleIds = module?._visibleIds || module?._prevVisibleIds || null;
190
+ if (visibleIds?.forEach) {
191
+ let found = false;
192
+ visibleIds.forEach(nodeId => {
193
+ if (found) {
194
+ return;
195
+ }
196
+
197
+ const entry = module?.nodeObjectsById?.get?.(normalizeId(nodeId)) || null;
198
+ if (!entry || entry.currentType !== 'CSS' || entry.cssObject?.visible !== true) {
199
+ return;
200
+ }
201
+
202
+ if (isLiveInteractiveOverlayEntry(entry) && supportsPassiveDisplay(entry)) {
203
+ found = true;
204
+ }
205
+ });
206
+
207
+ if (found) {
208
+ return true;
209
+ }
210
+ }
211
+
212
+ const selectedId = normalizeId(module?.selectedNodeIdJs);
213
+ if (selectedId) {
214
+ const selectedEntry = module?.nodeObjectsById?.get?.(selectedId) || null;
215
+ if (selectedEntry?.currentType === 'CSS' &&
216
+ selectedEntry.cssObject?.visible === true &&
217
+ isLiveInteractiveOverlayEntry(selectedEntry) &&
218
+ supportsPassiveDisplay(selectedEntry)) {
219
+ return true;
220
+ }
221
+ }
222
+
223
+ return false;
224
+ }
225
+
175
226
  function getCurrentLodBand(module) {
176
227
  const explicitBand = String(module?.lodRenderer?._currentLodBand || '').trim().toUpperCase();
177
228
  if (explicitBand) {
@@ -248,7 +299,7 @@
248
299
  state.passiveNearStickyUntil = 0;
249
300
  }
250
301
 
251
- return false;
302
+ return hasVisibleLiveInteractiveOverlayCandidate(module);
252
303
  }
253
304
 
254
305
  function shouldUseVisiblePassiveOverlayCandidates(module) {
@@ -1097,7 +1148,8 @@
1097
1148
  }
1098
1149
 
1099
1150
  function createReadonlyLiveSourcePortal(entry, card, options = {}) {
1100
- if (!entry || !card || options.interactive === true) {
1151
+ const liveInteractive = options.liveInteractive === true || isLiveInteractiveOverlayEntry(entry);
1152
+ if (!entry || !card || (options.interactive === true && liveInteractive !== true)) {
1101
1153
  return null;
1102
1154
  }
1103
1155
 
@@ -1108,10 +1160,15 @@
1108
1160
  }
1109
1161
 
1110
1162
  existingPortal.cardElement = card;
1163
+ existingPortal.liveInteractive = liveInteractive;
1164
+ existingPortal.sourceElement.style.pointerEvents = liveInteractive ? 'auto' : 'none';
1165
+ existingPortal.sourceElement.style.userSelect = liveInteractive ? '' : 'none';
1166
+ existingPortal.sourceElement.style.webkitUserSelect = liveInteractive ? '' : 'none';
1111
1167
  return {
1112
1168
  container: existingPortal.sourceElement,
1113
1169
  sourceRoot: existingPortal.sourceElement,
1114
- liveSource: true
1170
+ liveSource: true,
1171
+ liveInteractive: liveInteractive
1115
1172
  };
1116
1173
  }
1117
1174
 
@@ -1138,19 +1195,21 @@
1138
1195
  zoom: sourceElement.style.zoom,
1139
1196
  pointerEvents: sourceElement.style.pointerEvents,
1140
1197
  userSelect: sourceElement.style.userSelect,
1141
- webkitUserSelect: sourceElement.style.webkitUserSelect
1198
+ webkitUserSelect: sourceElement.style.webkitUserSelect,
1199
+ liveInteractive: liveInteractive
1142
1200
  };
1143
1201
 
1144
1202
  sourceElement.classList.add('mind-map-text-overlay-v2-live-source');
1145
- sourceElement.style.pointerEvents = 'none';
1146
- sourceElement.style.userSelect = 'none';
1147
- sourceElement.style.webkitUserSelect = 'none';
1203
+ sourceElement.style.pointerEvents = liveInteractive ? 'auto' : 'none';
1204
+ sourceElement.style.userSelect = liveInteractive ? '' : 'none';
1205
+ sourceElement.style.webkitUserSelect = liveInteractive ? '' : 'none';
1148
1206
  card.appendChild(sourceElement);
1149
1207
 
1150
1208
  return {
1151
1209
  container: sourceElement,
1152
1210
  sourceRoot: sourceElement,
1153
- liveSource: true
1211
+ liveSource: true,
1212
+ liveInteractive: liveInteractive
1154
1213
  };
1155
1214
  }
1156
1215
 
@@ -2351,6 +2410,25 @@
2351
2410
  target.addEventListener('mousedown', handler, { passive: false });
2352
2411
  }
2353
2412
 
2413
+ function isLiveOverlayControlTarget(target) {
2414
+ return !!target?.closest?.([
2415
+ 'button',
2416
+ 'input',
2417
+ 'textarea',
2418
+ 'select',
2419
+ '[contenteditable="true"]',
2420
+ '[data-template-card-interactive="true"]',
2421
+ '[data-template-card-action]',
2422
+ '[data-template-option-id]',
2423
+ '[data-remote-fleet-action]',
2424
+ '[data-remote-fleet-device-preview]',
2425
+ '[data-remote-fleet-control-popup]',
2426
+ '[data-remote-fleet-task-input]',
2427
+ '[data-remote-fleet-ai-toggle]',
2428
+ '[data-remote-fleet-search]'
2429
+ ].join(', '));
2430
+ }
2431
+
2354
2432
  function bindReadonlyOverlayPrimaryPointerRouting(module, root, sourceRoot) {
2355
2433
  if (!module || !root || typeof root.addEventListener !== 'function') {
2356
2434
  return;
@@ -2373,6 +2451,10 @@
2373
2451
  return;
2374
2452
  }
2375
2453
 
2454
+ if (isLiveOverlayControlTarget(event.target)) {
2455
+ return;
2456
+ }
2457
+
2376
2458
  const nodeId =
2377
2459
  normalizeId(root.dataset.nodeId) ||
2378
2460
  normalizeId(root._mindMapReadonlyOverlaySourceRoot?.dataset?.nodeId) ||
@@ -2894,6 +2976,13 @@
2894
2976
 
2895
2977
  function createReadonlySelectionShell(module, entry, options = {}) {
2896
2978
  const mode = getReadonlySelectionMode(entry);
2979
+ if (isLiveInteractiveOverlayMode(mode)) {
2980
+ return createReadonlyLiveSourcePortal(entry, options.cardElement, {
2981
+ ...options,
2982
+ liveInteractive: true
2983
+ });
2984
+ }
2985
+
2897
2986
  if (mode === 'agent-memo') {
2898
2987
  // Agent memo nodes must mirror the CSS3D source as-is. Their
2899
2988
  // auxiliary plan/console panels live outside the simplified memo
@@ -3294,7 +3383,11 @@
3294
3383
  card.dataset.sourceEpoch === sourceEpoch &&
3295
3384
  card.childElementCount > 0) {
3296
3385
  setCardMode(card, 'selection', interactive);
3297
- if (card.dataset.sourceKind !== 'live') {
3386
+ const liveInteractive = card.dataset.liveInteractive === 'true';
3387
+ if (liveInteractive) {
3388
+ card.style.pointerEvents = 'auto';
3389
+ bindReadonlyOverlayPrimaryPointerRouting(module, card, sourceRoot);
3390
+ } else if (card.dataset.sourceKind !== 'live') {
3298
3391
  bindReadonlyOverlayPrimaryPointerRouting(module, card, sourceRoot);
3299
3392
  refreshOverlayCloneInteractivity(module, card.firstElementChild || card, interactive, sourceRoot);
3300
3393
  syncReadonlyOverlayCardScrollFromSource(card);
@@ -3326,9 +3419,15 @@
3326
3419
  return null;
3327
3420
  }
3328
3421
 
3422
+ const liveInteractive = shellResult?.liveInteractive === true;
3329
3423
  card.dataset.sourceKind = shellResult?.liveSource === true ? 'live' : 'clone';
3424
+ card.dataset.liveInteractive = liveInteractive ? 'true' : 'false';
3425
+ card.classList.toggle('is-live-interactive', liveInteractive);
3330
3426
  card.appendChild(shell);
3331
- if (card.dataset.sourceKind !== 'live') {
3427
+ if (liveInteractive) {
3428
+ card.style.pointerEvents = 'auto';
3429
+ bindReadonlyOverlayPrimaryPointerRouting(module, card, shellSourceRoot);
3430
+ } else if (card.dataset.sourceKind !== 'live') {
3332
3431
  bindReadonlyOverlayPrimaryPointerRouting(module, card, shellSourceRoot);
3333
3432
  syncReadonlyOverlayCardScrollFromSource(card);
3334
3433
  scheduleReadonlyOverlayCardScrollSync(card);
@@ -3698,6 +3797,29 @@
3698
3797
  }
3699
3798
  }
3700
3799
 
3800
+ function hasLiveInteractiveOverlay(module) {
3801
+ const state = ensureState(module);
3802
+ if (state?.cards?.forEach) {
3803
+ let hasVisibleLiveCard = false;
3804
+ state.cards.forEach(card => {
3805
+ if (hasVisibleLiveCard || !card || card.style.display === 'none') {
3806
+ return;
3807
+ }
3808
+
3809
+ if (card.dataset?.sourceKind === 'live' &&
3810
+ card.dataset?.liveInteractive === 'true') {
3811
+ hasVisibleLiveCard = true;
3812
+ }
3813
+ });
3814
+
3815
+ if (hasVisibleLiveCard) {
3816
+ return true;
3817
+ }
3818
+ }
3819
+
3820
+ return hasVisibleLiveInteractiveOverlayCandidate(module);
3821
+ }
3822
+
3701
3823
  function setPassiveOverlaySuppressed(module, suppressed) {
3702
3824
  const state = ensureState(module);
3703
3825
  const layer = state?.layer;
@@ -3735,11 +3857,16 @@
3735
3857
  });
3736
3858
  clearLayerTransform(layer);
3737
3859
  layer.style.display = 'none';
3860
+ state.dirtyLayout = true;
3861
+ module._overlayDirty = true;
3862
+ module._lastOverlayKey = '';
3738
3863
  return true;
3739
3864
  }
3740
3865
 
3741
- layer.style.display = Array.from(state.cards.values()).some(card =>
3742
- !!card && card.style.display !== 'none') ? '' : 'none';
3866
+ state.dirtyLayout = true;
3867
+ module._overlayDirty = true;
3868
+ module._lastOverlayKey = '';
3869
+ layer.style.display = 'none';
3743
3870
  return true;
3744
3871
  }
3745
3872
 
@@ -4318,6 +4445,7 @@
4318
4445
  purgeMediaOverlayCards: purgeMediaOverlayCards,
4319
4446
  suspendSource: suspendSource,
4320
4447
  resumeSource: resumeSource,
4448
+ hasLiveInteractiveOverlay: hasLiveInteractiveOverlay,
4321
4449
  syncReadonlySourceScroll: syncReadonlySourceScroll
4322
4450
  };
4323
4451
  })();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-Br4DWyqxlRmH44i0F0OYs/cbiMcQZSXhuRDCRobDEAQ=",
4
+ "hash": "sha256-ncmibpfP4OVaoSZXQLmDLiOOSi8GW6wTmwlKPOWGtWk=",
5
5
  "fingerprinting": {
6
6
  "Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
7
7
  "Markdig.d1j7v41cl1.dll": "Markdig.dll",
@@ -131,7 +131,7 @@
131
131
  "MindExecution.Plugins.Directory.zc8ffaoknd.dll": "MindExecution.Plugins.Directory.dll",
132
132
  "MindExecution.Plugins.PlanMaster.flzcb87jvl.dll": "MindExecution.Plugins.PlanMaster.dll",
133
133
  "MindExecution.Plugins.YouTube.q4tvods1po.dll": "MindExecution.Plugins.YouTube.dll",
134
- "MindExecution.Shared.jv6r2n1bvg.dll": "MindExecution.Shared.dll",
134
+ "MindExecution.Shared.r8pan6upd8.dll": "MindExecution.Shared.dll",
135
135
  "MindExecution.Web.3b8az6ed0q.dll": "MindExecution.Web.dll",
136
136
  "dotnet.js": "dotnet.js",
137
137
  "dotnet.native.qc8g39g30v.js": "dotnet.native.js",
@@ -282,7 +282,7 @@
282
282
  "MindExecution.Kernel.pbzp3jfync.dll": "sha256-Ff6WHyLD39V0fEjUiQlxX9Y+edssyTH+7T4zfBdj3s0=",
283
283
  "MindExecution.Plugins.Concept.ksc3wkuptm.dll": "sha256-fIy3+/z7i12WktCVlAHG6hJGVOSgzWJNGXiDrArviYU=",
284
284
  "MindExecution.Plugins.PlanMaster.flzcb87jvl.dll": "sha256-zYXs1kS13yT6eDgbsthOX4Ku1n3P+TnPn8oIhJVwxQ0=",
285
- "MindExecution.Shared.jv6r2n1bvg.dll": "sha256-cdYJze5sGTmNGOvWL+BktfURuCHsKmec9PB0emQVJ38=",
285
+ "MindExecution.Shared.r8pan6upd8.dll": "sha256-Sw26dtjM8Rd82Nk3uWpkPPjrzCULyX1GwGdX9uJ0zzw=",
286
286
  "MindExecution.Web.3b8az6ed0q.dll": "sha256-cbwDzpFNXJ2mcIVtZC6fNkvXq4K+q0QTXJ5EGuTKL7w="
287
287
  },
288
288
  "lazyAssembly": {
@@ -7,8 +7,8 @@
7
7
  <title>MindExec | Run your ideas as AI task graphs</title>
8
8
  <meta name="description" content="MindExec is an AI execution canvas for solo builders, researchers, developers, and creators. Start with free browser tools, then move serious work into saved MindCanvas projects." />
9
9
  <base href="/" />
10
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260616-remote-live-fresh-v563" />
11
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260616-remote-live-fresh-v563" />
10
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260616-live-template-overlay-v565" />
11
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260616-live-template-overlay-v565" />
12
12
  <!-- ?쇄뼹??Font Awesome (local) ?쇄뼹??-->
13
13
  <link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
14
14
  <!-- ?꿎뼯??-->
@@ -579,7 +579,7 @@
579
579
  }
580
580
 
581
581
  const base = '_content/MindExecution.Shared/js/';
582
- const scriptVersion = '20260616-remote-live-fresh-v563';
582
+ const scriptVersion = '20260616-live-template-overlay-v565';
583
583
  const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
584
584
  console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
585
585
  const criticalScripts = [
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "0GkQkAf6",
2
+ "version": "nqE9sVux",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -42,7 +42,7 @@
42
42
  "url": "_content/MindExecution.Shared/css/app.css"
43
43
  },
44
44
  {
45
- "hash": "sha256-bM3TPSd4WDlrAJjzMh91OLXSpkFX5/3qUs84piTAEKA=",
45
+ "hash": "sha256-Z/qOemFxT1byK3tSyusCzWleiFLxcMRdsEc/0DoSPbk=",
46
46
  "url": "_content/MindExecution.Shared/css/mind-map-overrides.css"
47
47
  },
48
48
  {
@@ -78,7 +78,7 @@
78
78
  "url": "_content/MindExecution.Shared/js/marked.min.js"
79
79
  },
80
80
  {
81
- "hash": "sha256-zhbWABqHMZ+nPWlMMRuTFz6AfkMn5aOwZ9u63V1oW68=",
81
+ "hash": "sha256-znNKrMbupuP7uSHjadUem9zeSkWfr11mN7gBXZ7p4DY=",
82
82
  "url": "_content/MindExecution.Shared/js/mind-map-core.js"
83
83
  },
84
84
  {
@@ -86,7 +86,7 @@
86
86
  "url": "_content/MindExecution.Shared/js/mind-map-core.js.backup"
87
87
  },
88
88
  {
89
- "hash": "sha256-DhSn/UhaZNiUWVI6SxAXUCT4ZJ1rTb0M4ZAzWBF4ibU=",
89
+ "hash": "sha256-7zaPQ47/AyOgHHbIAFLHteRif2MsuDB8icBUaYDhkXg=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -154,7 +154,7 @@
154
154
  "url": "_content/MindExecution.Shared/js/mind-map-text-lod-system.js"
155
155
  },
156
156
  {
157
- "hash": "sha256-0gAWq58h1V8S1FBvthDq1MC09ltzbd/ef99MMKhSFzw=",
157
+ "hash": "sha256-qcrEPMkOzb7X1WFU1WcjRL2CBwOT/5xI62dUuyx2GUs=",
158
158
  "url": "_content/MindExecution.Shared/js/mind-map-text-overlay-v2.js"
159
159
  },
160
160
  {
@@ -442,8 +442,8 @@
442
442
  "url": "_framework/MindExecution.Plugins.YouTube.q4tvods1po.dll"
443
443
  },
444
444
  {
445
- "hash": "sha256-cdYJze5sGTmNGOvWL+BktfURuCHsKmec9PB0emQVJ38=",
446
- "url": "_framework/MindExecution.Shared.jv6r2n1bvg.dll"
445
+ "hash": "sha256-Sw26dtjM8Rd82Nk3uWpkPPjrzCULyX1GwGdX9uJ0zzw=",
446
+ "url": "_framework/MindExecution.Shared.r8pan6upd8.dll"
447
447
  },
448
448
  {
449
449
  "hash": "sha256-cbwDzpFNXJ2mcIVtZC6fNkvXq4K+q0QTXJ5EGuTKL7w=",
@@ -770,7 +770,7 @@
770
770
  "url": "_framework/Websocket.Client.vapounvmnl.dll"
771
771
  },
772
772
  {
773
- "hash": "sha256-5j809S+7v/sq5DbtGGZHh2z8V4kL+rCKD7nhboJYuxQ=",
773
+ "hash": "sha256-X5tMd8TgdpyfWLfjIOQZ6EsVxGF+b/KYBX2d/htH6Qo=",
774
774
  "url": "_framework/blazor.boot.json"
775
775
  },
776
776
  {
@@ -834,7 +834,7 @@
834
834
  "url": "image-manifest.json"
835
835
  },
836
836
  {
837
- "hash": "sha256-2B93M5xFDpgqUOcnXJPakFVZ1W1wwThzsOo3U1cQtto=",
837
+ "hash": "sha256-jFFpysUWXlCTjpS5auSogsacZmbe/Xlys2VAhvG/Guw=",
838
838
  "url": "index.html"
839
839
  },
840
840
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: 0GkQkAf6 */
1
+ /* Manifest version: nqE9sVux */
2
2
  // Hosted deployments should prefer the network over stale offline caches.
3
3
  // This service worker immediately clears old Blazor offline caches and unregisters itself.
4
4