@mindexec/cli 0.2.53 → 0.2.54

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.53",
3
+ "version": "0.2.54",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -649,6 +649,7 @@ try {
649
649
  const { manager, document } = await loadCss3DManager();
650
650
  assert.equal(typeof manager?.renderRemoteFleetMonitorForTest, 'function');
651
651
  assert.equal(typeof manager?.renderRemoteFleetDeviceForTest, 'function');
652
+ assert.equal(typeof manager?.applyRemoteFleetFramePatchesForTest, 'function');
652
653
  assert.equal(typeof manager?.setModuleForTest, 'function');
653
654
 
654
655
  const dotNetCalls = [];
@@ -724,6 +725,24 @@ try {
724
725
  assert.ok(initialDetailPanel?.textContent.includes('Load'));
725
726
  assert.ok(cards[0]?.querySelector('[data-remote-fleet-device-preview="tile"]'));
726
727
  assert.equal(/\b(Seen|Uptime|Mem|Load)\b/.test(cards[0]?.textContent || ''), false);
728
+ const patchTarget = devices.find(device => device.ThumbnailEnabled === true && device.LiveStreamActive !== true);
729
+ assert.ok(patchTarget);
730
+ const patchCard = Array.from(cards).find(card => card.dataset.deviceId === patchTarget.DeviceId);
731
+ const patchPreview = patchCard?.querySelector('[data-remote-fleet-device-preview="tile"]');
732
+ assert.ok(patchPreview);
733
+ const patchUrl = `/api/remote/devices/${encodeURIComponent(patchTarget.DeviceId)}/thumbnail?token=render-smoke-frame&seq=9999`;
734
+ const patchCount = manager.applyRemoteFleetFramePatchesForTest(bodyView, [{
735
+ deviceId: patchTarget.DeviceId,
736
+ kind: 'thumbnail',
737
+ frameSeq: 9999,
738
+ frameUrl: patchUrl,
739
+ receivedAt: new Date().toISOString()
740
+ }]);
741
+ assert.equal(patchCount, 1);
742
+ assert.equal(patchPreview.dataset.remoteFleetFrameSeq, '9999');
743
+ assert.equal(patchPreview.dataset.remoteFleetFrameUrl, patchUrl);
744
+ assert.equal(patchPreview.dataset.remoteFleetPendingFrameUrl || '', '');
745
+ assert.equal(patchPreview.querySelector('img[data-remote-fleet-frame-image="true"]')?.dataset.remoteFleetFrameUrl, patchUrl);
727
746
  const alternateDevice = devices.find(device => device.DeviceId !== focusedDevice.DeviceId);
728
747
  assert.ok(alternateDevice);
729
748
  const alternateCard = Array.from(cards).find(card => card.dataset.deviceId === alternateDevice.DeviceId);
@@ -13093,15 +13093,37 @@
13093
13093
  image.loading = frame.kind === 'thumbnail' ? 'lazy' : 'eager';
13094
13094
  image.decoding = 'async';
13095
13095
  image.style.cssText = 'width:100%;height:100%;object-fit:cover;display:block;';
13096
- const placeholder = preview?.querySelector?.('[data-remote-fleet-screen-placeholder="true"]');
13097
- if (placeholder) {
13098
- placeholder.remove();
13096
+ if (typeof preview?.insertBefore === 'function') {
13097
+ preview.insertBefore(image, preview.firstChild || null);
13098
+ } else {
13099
+ preview?.appendChild?.(image);
13099
13100
  }
13100
- preview?.insertBefore?.(image, preview.firstChild || null);
13101
13101
  return image;
13102
13102
  }
13103
13103
 
13104
- function applyRemoteFleetFramePatchToPreview(preview, frame) {
13104
+ function getRemoteFleetFrameIdentity(frame) {
13105
+ return [
13106
+ String(frame?.deviceId || '').trim(),
13107
+ String(frame?.kind || '').trim().toLowerCase(),
13108
+ String(frame?.streamId || '').trim(),
13109
+ String(Number(frame?.frameSeq || 0) || 0),
13110
+ String(frame?.frameUrl || '').trim()
13111
+ ].join('|');
13112
+ }
13113
+
13114
+ function cloneRemoteFleetFramePatch(frame) {
13115
+ return {
13116
+ deviceId: String(frame?.deviceId || '').trim(),
13117
+ kind: String(frame?.kind || 'thumbnail').trim().toLowerCase(),
13118
+ frameSeq: Number.isFinite(Number(frame?.frameSeq)) ? Math.floor(Number(frame.frameSeq)) : 0,
13119
+ frameUrl: String(frame?.frameUrl || '').trim(),
13120
+ receivedAt: String(frame?.receivedAt || '').trim(),
13121
+ capturedAt: String(frame?.capturedAt || '').trim(),
13122
+ streamId: String(frame?.streamId || '').trim()
13123
+ };
13124
+ }
13125
+
13126
+ function isRemoteFleetFrameNewerForPreview(preview, frame, comparePending = false) {
13105
13127
  if (!preview || !frame || !isRemoteFleetFrameSource(frame.frameUrl)) {
13106
13128
  return false;
13107
13129
  }
@@ -13118,11 +13140,73 @@
13118
13140
  return false;
13119
13141
  }
13120
13142
 
13121
- const image = ensureRemoteFleetFrameImage(preview, frame);
13122
- if (!image) {
13143
+ if (comparePending) {
13144
+ const pendingUrl = String(preview.dataset.remoteFleetPendingFrameUrl || '');
13145
+ const pendingKind = String(preview.dataset.remoteFleetPendingFrameKind || '').toLowerCase();
13146
+ const pendingSeq = Number(preview.dataset.remoteFleetPendingFrameSeq || '0');
13147
+ if (pendingUrl) {
13148
+ const samePending = pendingKind === frame.kind
13149
+ && pendingSeq === nextSeq
13150
+ && pendingUrl === frame.frameUrl;
13151
+ if (samePending) {
13152
+ return false;
13153
+ }
13154
+
13155
+ if (pendingKind === 'live' && frame.kind !== 'live') {
13156
+ return false;
13157
+ }
13158
+
13159
+ if (pendingKind === frame.kind
13160
+ && Number.isFinite(pendingSeq)
13161
+ && pendingSeq > 0
13162
+ && Number.isFinite(nextSeq)
13163
+ && nextSeq > 0
13164
+ && nextSeq < pendingSeq) {
13165
+ return false;
13166
+ }
13167
+ }
13168
+ }
13169
+
13170
+ return true;
13171
+ }
13172
+
13173
+ function ensureRemoteFleetFrameBadge(preview, frame) {
13174
+ let badge = preview?.querySelector?.('[data-remote-fleet-frame-badge="true"]');
13175
+ if (badge) {
13176
+ return badge;
13177
+ }
13178
+
13179
+ badge = document.createElement('span');
13180
+ badge.dataset.remoteFleetFrameBadge = 'true';
13181
+ const previewMode = String(preview?.dataset?.remoteFleetDevicePreview || '');
13182
+ const isDetail = previewMode === 'detail';
13183
+ badge.style.cssText = `
13184
+ position: absolute;
13185
+ right: ${isDetail ? '9px' : '6px'};
13186
+ bottom: ${isDetail ? '9px' : '6px'};
13187
+ max-width: calc(100% - ${isDetail ? '18px' : '12px'});
13188
+ padding: ${isDetail ? '4px 7px' : '3px 6px'};
13189
+ border-radius: 999px;
13190
+ background: ${frame?.kind === 'live' ? 'rgba(220, 38, 38, 0.84)' : 'rgba(15, 23, 42, 0.72)'};
13191
+ color: #e2e8f0;
13192
+ font-size: ${isDetail ? '9px' : '8px'};
13193
+ font-weight: 950;
13194
+ line-height: 1;
13195
+ overflow: hidden;
13196
+ text-overflow: ellipsis;
13197
+ white-space: nowrap;
13198
+ letter-spacing: 0;
13199
+ `;
13200
+ preview?.appendChild?.(badge);
13201
+ return badge;
13202
+ }
13203
+
13204
+ function commitRemoteFleetFrameToPreview(preview, image, frame) {
13205
+ if (!preview || !image || !isRemoteFleetFrameNewerForPreview(preview, frame, false)) {
13123
13206
  return false;
13124
13207
  }
13125
13208
 
13209
+ const nextSeq = Number(frame.frameSeq || 0);
13126
13210
  image.dataset.remoteFleetFrameKind = frame.kind;
13127
13211
  image.dataset.remoteFleetFrameSeq = String(nextSeq || 0);
13128
13212
  image.dataset.remoteFleetFrameUrl = frame.frameUrl;
@@ -13136,7 +13220,12 @@
13136
13220
  preview.dataset.remoteFleetFrameUrl = frame.frameUrl;
13137
13221
  preview.dataset.remoteFleetFrameAt = frame.receivedAt || frame.capturedAt || '';
13138
13222
 
13139
- const badge = preview.querySelector('[data-remote-fleet-frame-badge="true"]');
13223
+ const placeholder = preview.querySelector('[data-remote-fleet-screen-placeholder="true"]');
13224
+ if (placeholder) {
13225
+ placeholder.remove();
13226
+ }
13227
+
13228
+ const badge = ensureRemoteFleetFrameBadge(preview, frame);
13140
13229
  if (badge) {
13141
13230
  const at = frame.receivedAt || frame.capturedAt || '';
13142
13231
  badge.textContent = frame.kind === 'live'
@@ -13151,6 +13240,96 @@
13151
13240
  return true;
13152
13241
  }
13153
13242
 
13243
+ function clearRemoteFleetPendingFrameDataset(preview, frame) {
13244
+ if (!preview) {
13245
+ return;
13246
+ }
13247
+
13248
+ if (!frame
13249
+ || getRemoteFleetFrameIdentity(preview._remoteFleetPendingFrame) === getRemoteFleetFrameIdentity(frame)) {
13250
+ delete preview.dataset.remoteFleetPendingFrameKind;
13251
+ delete preview.dataset.remoteFleetPendingFrameSeq;
13252
+ delete preview.dataset.remoteFleetPendingFrameUrl;
13253
+ preview._remoteFleetPendingFrame = null;
13254
+ }
13255
+ }
13256
+
13257
+ function processRemoteFleetFrameQueue(preview, image) {
13258
+ if (!preview || !image || preview._remoteFleetFrameLoaderActive === true) {
13259
+ return;
13260
+ }
13261
+
13262
+ const frame = preview._remoteFleetPendingFrame;
13263
+ if (!frame || !isRemoteFleetFrameSource(frame.frameUrl)) {
13264
+ clearRemoteFleetPendingFrameDataset(preview, frame);
13265
+ return;
13266
+ }
13267
+
13268
+ preview._remoteFleetFrameLoaderActive = true;
13269
+ const frameIdentity = getRemoteFleetFrameIdentity(frame);
13270
+ const finish = loaded => {
13271
+ const currentPending = preview._remoteFleetPendingFrame;
13272
+ const stillLatest = getRemoteFleetFrameIdentity(currentPending) === frameIdentity;
13273
+ let committed = false;
13274
+ if (loaded && stillLatest) {
13275
+ committed = commitRemoteFleetFrameToPreview(preview, image, frame);
13276
+ window.RuntimeTrace?.emit?.('remote.frame.uiPatched', {
13277
+ count: committed ? 1 : 0,
13278
+ kind: frame.kind,
13279
+ seq: frame.frameSeq
13280
+ });
13281
+ }
13282
+
13283
+ if (stillLatest) {
13284
+ clearRemoteFleetPendingFrameDataset(preview, frame);
13285
+ }
13286
+
13287
+ preview._remoteFleetFrameLoaderActive = false;
13288
+ if (preview._remoteFleetPendingFrame) {
13289
+ processRemoteFleetFrameQueue(preview, image);
13290
+ }
13291
+ };
13292
+
13293
+ if (typeof Image !== 'function') {
13294
+ finish(true);
13295
+ return;
13296
+ }
13297
+
13298
+ const loader = new Image();
13299
+ loader.decoding = 'async';
13300
+ loader.onload = () => {
13301
+ const decoded = typeof loader.decode === 'function'
13302
+ ? loader.decode().catch(() => undefined)
13303
+ : Promise.resolve();
13304
+ decoded.then(() => finish(true));
13305
+ };
13306
+ loader.onerror = () => finish(false);
13307
+ loader.src = frame.frameUrl;
13308
+ }
13309
+
13310
+ function queueRemoteFleetFrameImageSwap(preview, frame) {
13311
+ if (!preview || !frame || !isRemoteFleetFrameNewerForPreview(preview, frame, true)) {
13312
+ return false;
13313
+ }
13314
+
13315
+ const image = ensureRemoteFleetFrameImage(preview, frame);
13316
+ if (!image) {
13317
+ return false;
13318
+ }
13319
+
13320
+ const nextFrame = cloneRemoteFleetFramePatch(frame);
13321
+ preview._remoteFleetPendingFrame = nextFrame;
13322
+ preview.dataset.remoteFleetPendingFrameKind = nextFrame.kind;
13323
+ preview.dataset.remoteFleetPendingFrameSeq = String(nextFrame.frameSeq || 0);
13324
+ preview.dataset.remoteFleetPendingFrameUrl = nextFrame.frameUrl;
13325
+ processRemoteFleetFrameQueue(preview, image);
13326
+ return true;
13327
+ }
13328
+
13329
+ function applyRemoteFleetFramePatchToPreview(preview, frame) {
13330
+ return queueRemoteFleetFrameImageSwap(preview, frame);
13331
+ }
13332
+
13154
13333
  function applyRemoteFleetFramePatches(bodyView, patches) {
13155
13334
  if (!bodyView || !Array.isArray(patches) || patches.length === 0) {
13156
13335
  return 0;
@@ -13178,7 +13357,7 @@
13178
13357
  });
13179
13358
 
13180
13359
  if (applied > 0) {
13181
- window.RuntimeTrace?.emit?.('remote.frame.uiPatched', {
13360
+ window.RuntimeTrace?.emit?.('remote.frame.uiQueued', {
13182
13361
  count: applied
13183
13362
  });
13184
13363
  }
@@ -19565,6 +19744,7 @@
19565
19744
  setModuleForTest: setModuleForTest,
19566
19745
  renderRemoteFleetMonitorForTest: renderRemoteFleetMonitor,
19567
19746
  renderRemoteFleetDeviceForTest: renderRemoteFleetDevice,
19747
+ applyRemoteFleetFramePatchesForTest: applyRemoteFleetFramePatches,
19568
19748
  renderBusinessAutomationEdges: renderBusinessAutomationEdges,
19569
19749
  scheduleBusinessAutomationEdgeRender: scheduleBusinessAutomationEdgeRender,
19570
19750
  syncBusinessAutomationSelectionContext: syncBusinessAutomationSelectionContext,
@@ -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=20260614-remote-frame-meta-v513" />
11
- <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260614-remote-frame-meta-v513" />
10
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260614-remote-frame-queue-v514" />
11
+ <link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260614-remote-frame-queue-v514" />
12
12
  <!-- ?쇄뼹??Font Awesome (local) ?쇄뼹??-->
13
13
  <link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
14
14
  <!-- ?꿎뼯??-->
@@ -558,7 +558,7 @@
558
558
  }
559
559
 
560
560
  const base = '_content/MindExecution.Shared/js/';
561
- const scriptVersion = '20260614-remote-frame-meta-v513';
561
+ const scriptVersion = '20260614-remote-frame-queue-v514';
562
562
  const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
563
563
  console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
564
564
  const criticalScripts = [
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "3rReX/U0",
2
+ "version": "AbrqsGjG",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -86,7 +86,7 @@
86
86
  "url": "_content/MindExecution.Shared/js/mind-map-core.js.backup"
87
87
  },
88
88
  {
89
- "hash": "sha256-U5R3dUgCFR7qo8wM4p3MlIDxa9ZCd686fnrWvQFfSfs=",
89
+ "hash": "sha256-Ha83zpDlwJT6nxD2wgO3rL3uPBHZvZFxzpnKKHMZhd0=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -834,7 +834,7 @@
834
834
  "url": "image-manifest.json"
835
835
  },
836
836
  {
837
- "hash": "sha256-KqDHFUlmca/5qM/MGimpiIQKNxh1Udxo7/O1bDIsk+s=",
837
+ "hash": "sha256-CSvUcpq/bag2h6q/jhgdebJ5n7IE9rrAbielPCFI5jk=",
838
838
  "url": "index.html"
839
839
  },
840
840
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: 3rReX/U0 */
1
+ /* Manifest version: AbrqsGjG */
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