@mindexec/cli 0.2.234 → 0.2.236

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.234",
3
+ "version": "0.2.236",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -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 = '20260620-wheel-zoom-hotpath-v681';
8
+ const MINDMAP_CORE_BUILD_ID = '20260620-zoom-settle-idle-v683';
9
9
  const CanvasPhase = Object.freeze({
10
10
  Booting: 'booting',
11
11
  BoardFileLoading: 'board-file-loading',
@@ -113,6 +113,7 @@
113
113
  const CAMERA_MOTION_VISUAL_ONLY_FAST_PATH_ENABLED = true;
114
114
  const CAMERA_MOTION_WEBGL_CANVAS_TRANSFORM_ENABLED = true;
115
115
  const CAMERA_STATIONARY_INTERACTION_FRAME_DELAY_MS = 48;
116
+ const CAMERA_ZOOM_END_DELAY_MS = 150;
116
117
  const CAMERA_MOTION_GLOBAL_STYLE_CLASS_ENABLED = false;
117
118
  const CAMERA_DENSE_GLOBAL_STYLE_CLASS_ENABLED = false;
118
119
  const PIPELINE_PROFILE_SECTION_KEYS = Object.freeze([
@@ -1053,6 +1054,7 @@
1053
1054
  stationaryVisual: 0,
1054
1055
  residentVisual: 0,
1055
1056
  earlyCameraOnly: 0,
1057
+ zoomSettleIdle: 0,
1056
1058
  css3dCameraFast: 0,
1057
1059
  normal: 0,
1058
1060
  visibilityCulling: 0,
@@ -1088,6 +1090,10 @@
1088
1090
  return 'ultra-camera-only';
1089
1091
  }
1090
1092
 
1093
+ if (frameProfile.uaZoomSettleIdle === true) {
1094
+ return 'zoom-settle-idle';
1095
+ }
1096
+
1091
1097
  if (frameProfile.uaVisualOnlyMotion === true) {
1092
1098
  return 'visual-only';
1093
1099
  }
@@ -1158,6 +1164,9 @@
1158
1164
  mode === 'stationary-camera-navigation') {
1159
1165
  stats.earlyCameraOnly += 1;
1160
1166
  }
1167
+ if (mode === 'zoom-settle-idle') {
1168
+ stats.zoomSettleIdle += 1;
1169
+ }
1161
1170
  if (frameProfile.usedCss3dCameraFastPath === true) {
1162
1171
  stats.css3dCameraFast += 1;
1163
1172
  }
@@ -1187,7 +1196,8 @@
1187
1196
  const visualOnlyTotal = Number(stats.visualOnly || 0) +
1188
1197
  Number(stats.stationaryVisual || 0) +
1189
1198
  Number(stats.residentVisual || 0) +
1190
- Number(stats.earlyCameraOnly || 0);
1199
+ Number(stats.earlyCameraOnly || 0) +
1200
+ Number(stats.zoomSettleIdle || 0);
1191
1201
  stats.visualOnlyPercent = Number((visualOnlyTotal / total * 100).toFixed(1));
1192
1202
  stats.cameraFastPercent = Number((Number(stats.css3dCameraFast || 0) / total * 100).toFixed(1));
1193
1203
  stats.normalPercent = Number((Number(stats.normal || 0) / total * 100).toFixed(1));
@@ -1318,6 +1328,156 @@
1318
1328
  }
1319
1329
  }
1320
1330
 
1331
+ function tryRunZoomSettleIdleFrame(module, loop, frameStart, isCameraMoving, shouldCaptureFramePerf, frameProfTimes, profileSection) {
1332
+ if (!module ||
1333
+ CAMERA_MOTION_VISUAL_ONLY_FAST_PATH_ENABLED !== true ||
1334
+ module.isZooming !== true ||
1335
+ isCameraMoving === true ||
1336
+ module.isPanning === true ||
1337
+ module.isLoading === true ||
1338
+ module.isSelecting === true ||
1339
+ module.isDraggingNode === true ||
1340
+ module.isDraggingMultipleNodes === true ||
1341
+ module.isResizing === true ||
1342
+ module.isWindowResizing === true ||
1343
+ module.useAnimation60Fps === true ||
1344
+ !module.camera) {
1345
+ return false;
1346
+ }
1347
+
1348
+ const lastZoomInput = Number(module._zoomInputTime || 0);
1349
+ if (lastZoomInput <= 0) {
1350
+ return false;
1351
+ }
1352
+
1353
+ const elapsedSinceZoomInput = frameStart - lastZoomInput;
1354
+ if (!Number.isFinite(elapsedSinceZoomInput) ||
1355
+ elapsedSinceZoomInput < 0 ||
1356
+ elapsedSinceZoomInput > CAMERA_ZOOM_END_DELAY_MS) {
1357
+ return false;
1358
+ }
1359
+
1360
+ const forceUpdateFrames = Math.max(0, Number(module._forceUpdateFrames || 0));
1361
+ const cameraNavigationForceFrames = Math.max(0, Number(module._cameraNavigationForceFrames || 0));
1362
+ const hasForcedUpdate = forceUpdateFrames > 0;
1363
+ const hasOnlyCameraNavigationForcedUpdate =
1364
+ hasForcedUpdate &&
1365
+ cameraNavigationForceFrames >= forceUpdateFrames;
1366
+ if (hasForcedUpdate && hasOnlyCameraNavigationForcedUpdate !== true) {
1367
+ return false;
1368
+ }
1369
+
1370
+ const hasEditingTextOverlayFocus = !!(
1371
+ String(module._textOverlayV2State?.editing?.nodeId || '').trim() ||
1372
+ String(module._editingOverlayState?.nodeId || '').trim()
1373
+ );
1374
+ if (hasEditingTextOverlayFocus) {
1375
+ return false;
1376
+ }
1377
+
1378
+ const hasPendingCss3dStructuralTransformWork = !!(
1379
+ (module._cssTransformDirtyIds?.size || 0) > 0 ||
1380
+ module._cssParentRepairNeeded === true
1381
+ );
1382
+ if (hasPendingCss3dStructuralTransformWork) {
1383
+ return false;
1384
+ }
1385
+
1386
+ if (module._css3dVisualChangedThisFrame === true ||
1387
+ module._css3dVisualChangedSinceLastRender === true) {
1388
+ module._css3dVisualDeferredForMotion = true;
1389
+ }
1390
+ if (module._overlayDirty === true ||
1391
+ String(module._textOverlayV2State?.selectionNodeId || '').trim() ||
1392
+ String(module._selectableTextOverlayNodeId || '').trim()) {
1393
+ module._deferPassiveOverlayRefresh = true;
1394
+ }
1395
+
1396
+ if (hasForcedUpdate) {
1397
+ module._forceUpdateFrames = Math.max(0, forceUpdateFrames - 1);
1398
+ if (cameraNavigationForceFrames > 0) {
1399
+ module._cameraNavigationForceFrames = Math.max(0, cameraNavigationForceFrames - 1);
1400
+ }
1401
+ }
1402
+
1403
+ module._lastVisibilityCullingSkipReason = 'ua-zoom-settle-idle';
1404
+ recordCameraMotionFastPathStatus(module, 'hit', 'ua-zoom-settle-idle');
1405
+ profileSection?.('uaZoomSettleIdle');
1406
+
1407
+ const frameEnd = typeof performance !== 'undefined' && typeof performance.now === 'function'
1408
+ ? performance.now()
1409
+ : Date.now();
1410
+ const frameDuration = frameEnd - frameStart;
1411
+ module._lastFrameDurationMs = frameDuration;
1412
+ module._lastFrameMetricsAt = frameEnd;
1413
+ module._lastWebglRenderInfo = {
1414
+ calls: 0,
1415
+ triangles: 0,
1416
+ points: 0,
1417
+ lines: 0,
1418
+ skipped: true,
1419
+ uaZoomSettleIdle: true
1420
+ };
1421
+
1422
+ if (shouldCaptureFramePerf) {
1423
+ const sectionTimes = {};
1424
+ Object.entries(frameProfTimes || {})
1425
+ .filter(([key, value]) => key !== 'visibleNodes' && typeof value === 'number')
1426
+ .forEach(([key, value]) => {
1427
+ sectionTimes[key] = Number(value.toFixed(2));
1428
+ });
1429
+ module._lastFramePerfProfile = {
1430
+ durationMs: Number(frameDuration.toFixed(2)),
1431
+ update: false,
1432
+ cameraZ: Number((module.camera?.position?.z || 0).toFixed(2)),
1433
+ isZooming: true,
1434
+ isPanning: false,
1435
+ isCameraMoving: false,
1436
+ isCameraNavigationActive: true,
1437
+ isInLodMode: module.lodRenderer?.isInLODMode === true,
1438
+ lodBand: module.lodRenderer?._currentLodBand || null,
1439
+ visibleNodes: Number(module._visibleIds?.size || module._prevVisibleIds?.size || 0),
1440
+ freezeVisibility: true,
1441
+ freezeLod: module.lodRenderer?.isInLODMode === true,
1442
+ freezeFullRes: module.lodRenderer?.isInLODMode !== true,
1443
+ residentMidFarStable: module.lodRenderer?.isInLODMode === true,
1444
+ residentDirty: false,
1445
+ residentBandChanging: false,
1446
+ viewSyncMode: 'ua-zoom-settle-idle',
1447
+ lodUpdateCalled: false,
1448
+ lodUpdateSkipped: true,
1449
+ lodUpdateSkipReason: 'ua-zoom-settle-idle',
1450
+ lodSkipReason: '',
1451
+ lodDirtyReason: '',
1452
+ lodDirtyState: null,
1453
+ viewSyncBreakdown: null,
1454
+ shouldRunVisibilityCulling: false,
1455
+ visibilityStableSkip: true,
1456
+ visibilitySkipReason: 'ua-zoom-settle-idle',
1457
+ incrementalPanVisibility: false,
1458
+ shouldSyncCss3dTransforms: false,
1459
+ shouldRenderCss3d: false,
1460
+ usedCss3dCameraFastPath: false,
1461
+ uaZoomSettleIdle: true,
1462
+ shouldSyncTextOverlays: false,
1463
+ usedPassiveOverlayCameraFastPath: false,
1464
+ passiveOverlaySuppressed: module._suppressPassiveDomOverlayDuringZoom === true,
1465
+ webgl: module._lastWebglRenderInfo || null,
1466
+ sections: sectionTimes
1467
+ };
1468
+ updateFramePerfPeakProfile(module, module._lastFramePerfProfile, frameEnd);
1469
+ } else if (module._lastFramePerfProfile) {
1470
+ module._lastFramePerfProfile = null;
1471
+ }
1472
+
1473
+ const remainingMs = Math.max(1, CAMERA_ZOOM_END_DELAY_MS - elapsedSinceZoomInput + 1);
1474
+ const nextDelayMs = Math.max(16, remainingMs);
1475
+ module._lastAnimationLoopDelayMs = nextDelayMs;
1476
+ module._animationLoopExecuting = false;
1477
+ module._scheduleAnimationLoop(loop, nextDelayMs);
1478
+ return true;
1479
+ }
1480
+
1321
1481
  function tryRunUltraEarlyCameraOnlyFrame(module, loop, frameStart, isCameraMoving, shouldCaptureFramePerf, frameProfTimes, profileSection) {
1322
1482
  const isCameraNavigationActive =
1323
1483
  isCameraMoving === true ||
@@ -3631,6 +3791,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
3631
3791
  this._lastLocalSnapGridKey = '';
3632
3792
  this._lastLocalSnapGridTransformKey = '';
3633
3793
  this._lastLocalSnapGridOpacity = '';
3794
+ this._localSnapGridStyleDeferredForZoom = false;
3634
3795
  this._lastSnapGridClientX = null;
3635
3796
  this._lastSnapGridClientY = null;
3636
3797
  this._animationIdleTimerId = null;
@@ -3751,6 +3912,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
3751
3912
  this._lastLocalSnapGridKey = '';
3752
3913
  this._lastLocalSnapGridTransformKey = '';
3753
3914
  this._lastLocalSnapGridOpacity = '';
3915
+ this._localSnapGridStyleDeferredForZoom = false;
3754
3916
  return layer;
3755
3917
  }
3756
3918
 
@@ -3781,6 +3943,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
3781
3943
  }
3782
3944
 
3783
3945
  this._localSnapGridVisible = false;
3946
+ this._localSnapGridStyleDeferredForZoom = false;
3784
3947
  if (layer.style.opacity !== '0') {
3785
3948
  layer.style.opacity = '0';
3786
3949
  }
@@ -3853,8 +4016,13 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
3853
4016
  Math.round(majorStepPx * 100),
3854
4017
  Math.round(opacity * 100)
3855
4018
  ].join('|');
4019
+ const shouldDeferLocalGridStyleForZoom =
4020
+ this.isZooming === true &&
4021
+ !!this._lastLocalSnapGridKey;
3856
4022
 
3857
- if (localGridKey !== this._lastLocalSnapGridKey) {
4023
+ if (localGridKey !== this._lastLocalSnapGridKey &&
4024
+ shouldDeferLocalGridStyleForZoom !== true) {
4025
+ this._localSnapGridStyleDeferredForZoom = false;
3858
4026
  this._lastLocalSnapGridKey = localGridKey;
3859
4027
  const opacityValue = opacity.toFixed(3);
3860
4028
  this._lastLocalSnapGridOpacity = opacityValue;
@@ -3880,6 +4048,8 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
3880
4048
  if (layer.style.opacity !== opacityValue) {
3881
4049
  layer.style.opacity = opacityValue;
3882
4050
  }
4051
+ } else if (shouldDeferLocalGridStyleForZoom === true) {
4052
+ this._localSnapGridStyleDeferredForZoom = true;
3883
4053
  }
3884
4054
 
3885
4055
  const transformKey = `${Math.round(layerLeft * 2)}|${Math.round(layerTop * 2)}`;
@@ -5848,12 +6018,11 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5848
6018
 
5849
6019
  // ▼▼▼ [Fix] 줌 종료 쿨다운 - 휠 입력 후 일정 시간 대기 ▼▼▼
5850
6020
  // _zoomInputTime은 interactions.js에서 휠 입력 시 설정됨
5851
- const ZOOM_END_DELAY_MS = 150; // 통일된 딜레이 (패닝 전환 여유 확보)
5852
- const zoomNow = performance.now();
5853
- const lastZoomInput = this._zoomInputTime || 0;
5854
- const timeSinceLastInput = zoomNow - lastZoomInput;
5855
-
5856
- if (this.isZooming && !isCameraMoving && timeSinceLastInput > ZOOM_END_DELAY_MS) {
6021
+ const zoomNow = performance.now();
6022
+ const lastZoomInput = this._zoomInputTime || 0;
6023
+ const timeSinceLastInput = zoomNow - lastZoomInput;
6024
+
6025
+ if (this.isZooming && !isCameraMoving && timeSinceLastInput > CAMERA_ZOOM_END_DELAY_MS) {
5857
6026
  this.isZooming = false;
5858
6027
  this.cssRenderer?.domElement?.classList?.remove?.('is-zooming');
5859
6028
  if (FRAME_PERF_DEBUG) {
@@ -5987,6 +6156,17 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5987
6156
  // 3. Unified Visibility & LOD Pass (One Loop to Rule Them All)
5988
6157
  // ----------------------------------------------------------------
5989
6158
  this.frameCount = (this.frameCount || 0) + 1;
6159
+ if (tryRunZoomSettleIdleFrame(
6160
+ this,
6161
+ loop,
6162
+ frameStart,
6163
+ isCameraMoving,
6164
+ shouldCaptureFramePerf,
6165
+ _frameProfTimes,
6166
+ _profileSection
6167
+ ) === true) {
6168
+ return;
6169
+ }
5990
6170
  if (tryRunUltraEarlyCameraOnlyFrame(
5991
6171
  this,
5992
6172
  loop,
@@ -7,8 +7,8 @@
7
7
  <title>MindExec | Business Execution OS for solo builders</title>
8
8
  <meta name="description" content="MindExec is an AI business execution OS for solo builders who want to turn notes, research, assets, and repeatable execution Skills into revenue-producing work." />
9
9
  <base href="/" />
10
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260620-wheel-zoom-hotpath-v681" />
11
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260620-wheel-zoom-hotpath-v681" />
10
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260620-zoom-settle-idle-v683" />
11
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260620-zoom-settle-idle-v683" />
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 = '20260620-wheel-zoom-hotpath-v681';
582
+ const scriptVersion = '20260620-zoom-settle-idle-v683';
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": "FOi7IcPO",
2
+ "version": "KArZP7YJ",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -78,7 +78,7 @@
78
78
  "url": "_content/MindExecution.Shared/js/marked.min.js"
79
79
  },
80
80
  {
81
- "hash": "sha256-HAcIKHR8GNq+hp/a1I7r69dToZn+z+Vu6zQ3zo+Sin8=",
81
+ "hash": "sha256-J1AAQdPBWPRzvMK4P6IyUry5TNB6qoLo8yhiW/ufe2k=",
82
82
  "url": "_content/MindExecution.Shared/js/mind-map-core.js"
83
83
  },
84
84
  {
@@ -834,7 +834,7 @@
834
834
  "url": "image-manifest.json"
835
835
  },
836
836
  {
837
- "hash": "sha256-nKh30c9Ax0h/31FBsTI98E174o6u1tGmWFlutqKFPeU=",
837
+ "hash": "sha256-c0UqlDqATxAedVrrky+NGpj/3I4LHORPhKK546n0Jso=",
838
838
  "url": "index.html"
839
839
  },
840
840
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: FOi7IcPO */
1
+ /* Manifest version: KArZP7YJ */
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